Shared GitHub configuration for Lameco projects.
Pin callers to a tag (e.g. @3.0.0), never @main — tags are immutable, so a
pipeline change can never break a repo until that repo explicitly bumps.
CI pipeline for Craft CMS repos. Gates: composer audit (CVE ratchet: a PR
fails only on advisories its base branch does not already have, so a security
burn-down doesn't drown the signal; zero backlog = strict), PHPStan (strict
when a phpstan.neon[.dist] exists), frontend assets (the exact
yarn install && yarn build the deploy runs — contract with lameco:build_assets
in deployer-tasks), a two-phase deploy simulation (install Craft at the base
branch, craft up at the PR ref), and the project test suite (auto-detected:
composer test script or a phpunit config — repos without one skip green, so the
gate needs no caller config). When a dependency bump needs project-config changes,
the craft-config-update job generates and pushes them onto the PR (requires org
secret CRAFT_CONFIG_UPDATE_TOKEN, a PAT — GITHUB_TOKEN pushes would not
re-trigger CI). ci / ci-ok is the fan-in job to use as the required status
check in branch rulesets.
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true # supersede stale runs on force-push
jobs:
ci:
uses: Lameco-Development/.github/.github/workflows/ci-craft.yml@3.0.0
secrets: inheritCI pipeline for Symfony repos. Gates: composer audit (CVE ratchet — see
ci-craft), PHPStan (strict when
a phpstan.neon[.dist] exists), boot/smoke (yaml/container/twig lint +
cache:warmup), an optional from-scratch migrations + schema-drift gate (pass
database-image), and the project test suite (auto-detected: composer test
script or a phpunit config — repos without one skip green). When database-image
is set, the tests gate also gets that DB with the test database created and
migrated, so functional suites work out of the box. Same ci / ci-ok fan-in for
rulesets.
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true # supersede stale runs on force-push
jobs:
ci:
uses: Lameco-Development/.github/.github/workflows/ci-symfony.yml@3.0.0
with:
database-image: mariadb:11 # optional — empty skips the DB gate
secrets: inheritCI pipeline for Node repos (Next.js, Vite/Angular SPAs, Node servers). Node version
from .nvmrc, package manager from the lockfile (npm / yarn / pnpm) — no inputs
needed. Gates: dependency audit (high+ CVEs), lint + typecheck (strict when
configured, warn when absent), test suite (auto-detected test script; npm's
"no test specified" placeholder skips green), and the production build. Same
ci / ci-ok fan-in for rulesets. Not for monorepos — those keep bespoke CI.
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true # supersede stale runs on force-push
jobs:
ci:
uses: Lameco-Development/.github/.github/workflows/ci-node.yml@3.0.0
secrets: inheritMigration note (2.0.0):
ci-php.yml(single workflow with astackinput) was split into the two stack workflows above and removed frommain. Callers pinned to1.xtags keep working — update them to the matching stack workflow when bumping.build-deploy-php.ymlwas removed too: it built assets in CI and deployed via Deployer, which double-builds now thatlameco:build_assetsruns the frontend build during every deploy — usedeploy-php.yml.
Migration note (3.0.0):
build-deploy-node.ymlwas renamed todeploy-node.yml(naming parity withdeploy-php.yml; its job is nowdeploytoo).craft-update-notes.ymlwas removed: its changelog-parsing PR comments added more noise than signal —composer auditin CI and the Renovate PR description cover the security/breaking-change story. Callers pinned to2.xtags keep working; drop thechangelogjob and switch todeploy-node.ymlwhen bumping.
Deploy workflow for PHP projects via Deployer. The frontend build happens inside
dep deploy (deployer-tasks lameco:build_assets), so this workflow needs no
build job. Binds to the GitHub Environment named after the target — add required
reviewers on the production Environment to gate deploys behind an approval.
Preflights that the target host in deploy.php is actually provisioned (no
%SERVER%/%USER% template placeholders) and fails with a clear message if not.
Always deploys the pushed ref (-o branch=<ref> overrides the host's static
branch in deploy.php, which stays canonical for manual dep deploy use);
deployer-tasks' lameco:verify_deploy_branch still enforces flow policy against
the overridden value. Gitflow guards: production refuses any ref but the default
branch (dispatch-from-feature-branch protection), and development pushes
skip-green while a release/* branch exists (the release owns staging).
jobs:
deploy:
uses: Lameco-Development/.github/.github/workflows/deploy-php.yml@3.0.0
with:
environment: production
secrets: inheritDeploy workflow for Node repos. Package manager detected from the lockfile
(npm / yarn / pnpm), Node from .nvmrc. Binds to the GitHub Environment named
after the target: protection rules, environment secrets, and environment vars.
Client-public build config (NEXT_PUBLIC_*, VITE_*, …) is read from those vars
at build time; a build:<environment> script wins over plain build (Angular
configurations). Two modes:
app(default) — rsync the repo to the VPS, install prod deps there, restart via supervisord. For anything that runs on the server.static— build on the runner, rsync only the built bundle (build-dir, defaultdist) to the webroot (vars.DEPLOY_PATH, defaultpublic_html/), with--delete. Nothing installs or restarts on the server. For Vite/Angular SPAs on (shared) hosting.
jobs:
deploy:
uses: Lameco-Development/.github/.github/workflows/deploy-node.yml@3.0.0
with:
environment: production
# mode: static # SPA bundle-only deploy
# build-dir: dist/my-app/browser # Angular 17+ output path
secrets:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
SSH_HOST: ${{ secrets.SSH_HOST }}
SSH_USER: ${{ secrets.SSH_USER }}Fails loudly when a second release/* branch is created (gitflow: one release at a
time). Wire it per repo with an on: create caller (wired in sbcl-admin + sbcl-api).
- guidelines/ — AI coding guidelines for Craft CMS, Tailwind CSS, JavaScript, and Twig
- docs/ — Craft CMS conventions checklist and Craft 4→5 upgrade guide
- renovate-config.json — Shared base Renovate preset (CVE→
main, routine→development). Repos extend it vialocal>Lameco-Development/.github:renovate-config. - renovate-craft.json — Craft overlay (never auto-merge; needs
craft up). Craft repos extend it in addition to the base. - renovate-global.js — Self-hosted Renovate global config (autodiscover / onboarding), used by renovate-selfhosted.yml.