Skip to content

Latest commit

 

History

130 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Genero GitHub Actions

Shared composite actions and reusable workflows for Genero's Bedrock/Sage WordPress projects.

Setup

This is a private repository. To allow other repos in the org to use these actions:

  1. Go to Settings → Actions → General on this repo
  2. Under "Access", select "Accessible from repositories in the 'generoi' organization"

Composite Actions

Action Description
setup PHP + Node.js setup with caching, Fontawesome and Packagist auth
install-wordpress MySQL + WP dev server install (single or multisite)
setup-ddev DDEV setup (pinned SHA)
ssh-agent SSH agent wrapper (pinned SHA)

Usage

- uses: generoi/github-actions/setup@v2
  with:
    npm_fontawesome_auth_token: ${{ secrets.NPM_FONTAWESOME_AUTH_TOKEN }}
    composer_bot_private_key: ${{ secrets.COMPOSER_BOT_PRIVATE_KEY }}

- uses: generoi/github-actions/install-wordpress@v1
  with:
    multisite: 'true'

Composer credentials

setup needs a credential that can read our private plugin repositories. Pass exactly one:

  • composer_bot_private_key — preferred. The private key for the genero-composer-bot GitHub App; the action mints an installation token per run, valid for an hour and revoked when the job ends.
  • packagist_github_token — the older path, a PAT on the generoi-deploy machine user. Still accepted so repositories can migrate one at a time.

Passing neither fails the run immediately rather than surfacing later as a 404 on a private package.

Both are handled by composer-auth, which setup calls after installing PHP. Use it directly only if you drive setup-php yourself and so cannot go through setupvulnerability-scan.yml is the one case in this repo. It must run after Composer exists, since it configures through composer config.

- uses: generoi/github-actions/composer-auth@v2
  with:
    composer_bot_private_key: ${{ secrets.COMPOSER_BOT_PRIVATE_KEY }}

Reusable Workflows

Workflow Description
test.yml Lint + install WP + smoke test + phpunit
deploy.yml SSH + build + test + deployer
e2e.yml Playwright E2E tests against a URL
vulnerability-scan.yml WP vuln scan + Google Chat notification
plugin-changelog.yml Comment wp.org changelogs for changed wp-plugin/*

Usage

jobs:
  test:
    uses: generoi/github-actions/.github/workflows/test.yml@v1
    secrets: inherit
    with:
      multisite: true
      smoke_grep: 'app/themes/gds/public/scripts/app.js'

Changelogs for wp-plugin/*

Dependabot renders release notes for every github-sourced package and nothing at all for wp-plugin/*: WP Packages publishes the wp.org SVN tag as the package source, and Dependabot only resolves git sources — then falls back to a metadata lookup hardcoded to repo.packagist.org, where those packages do not exist. No dependabot.yml setting changes either half.

plugin-changelog.yml fills the gap from api.wordpress.org instead. It runs only on Dependabot's PRs — a human opening a composer update PR picked the versions and already knows what moved. The caller owns the trigger and the token, because a reusable workflow can only narrow the caller's permissions, never widen them:

on:
  pull_request:
    paths:
      - composer.lock

permissions:
  contents: read
  pull-requests: write

jobs:
  changelog:
    if: github.event.pull_request.user.login == 'dependabot[bot]'
    uses: generoi/github-actions/.github/workflows/plugin-changelog.yml@v2

Keep that if even though the shared workflow guards on the author too: the job-level one skips the reusable-workflow call outright, while the shared one only runs after the call has been made.

Dependabot's pull_request events get a read-only token by default, but an explicit permissions: block still elevates it — so this needs no pull_request_target, and should not use one. Drop contents: read and the comment still posts, from a diff-hunk fallback that quietly misses plugins.

Scheduling the nightly scan

vulnerability-scan.yml does not sleep to spread load — runner time is billed, so the stagger belongs in the cron expression, which is free. Give each repo its own minute (and ideally its own hour) rather than copying 5 4 * * *:

on:
  schedule:
    - cron: '17 3 * * *' # unique per repo

Sharing one minute across repos means every scan hits the advisory and GitHub APIs simultaneously, and GitHub also delays runs scheduled on popular minutes.

Which repos the cron actually scans

The scheduled scan is gated on the repo's maintenance organization custom property. It runs only for monthly, bi-monthly, quarterly and critical-only; hosted-only, none and an unset property skip the run.

That means adding the workflow to a repo is not enough — the repo also needs a maintenance value, or its nightly scan silently no-ops:

gh api repos/generoi/<repo>/properties/values \
  --jq '.[] | select(.property_name == "maintenance") | .value'

Two deliberate escape hatches:

  • A manual workflow_dispatch always scans, whatever the tier.
  • If the property API call fails, the scan runs anyway. An untagged repo is a visible state someone can fix; a transient 5xx is not, and it must never silently skip a security scan.

Versioning

Projects pin to the major tag (@v1). Patch updates are automatic.

Dependabot monitors upstream action SHAs — merge its PRs to update all projects at once.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages