The /.github/workflows directory contains GitHub Actions workflows for continuous integration, deployment, and automation tasks.
Table of contents
- Workflows
Notes
- Every workflow runs on GitHub-hosted runners (
ubuntu-latest,ubuntu-24.04); no self-hosted runner is used any more - Python workflows use Python 3.x on Ubuntu runners for documentation generation
- Most workflows use concurrency groups to prevent duplicate runs and conserve resources
- Workflows are triggered by push events, pull requests, schedules, other workflow runs (
workflow_run), or manual dispatch (workflow_dispatch) - Repeated setup steps are factored out into composite actions under
.github/actions— see Composite Actions - Several workflows interact with scripts in /scripts/README.md
Continuous Integration and Testing
CI
Runs the pull request validation pipeline: an unconditional dependency review, plus lint/build/test jobs that are gated on which paths changed. Jobs are skipped when no relevant files were modified. Provides the CI Success status check required by branch protection rules.
Workflow properties
| Property | Value |
|---|---|
| Workflow | continuous-integration.yml |
| Workflow name | CI |
| Trigger | Pull requests to main branch (opened, synchronize, reopened) |
| Manual trigger | No — CI gates pull requests and has no meaning outside one (dependency-review only supports pull_request, and path detection needs a PR base SHA) |
| Runner | ubuntu-latest (GitHub-hosted) |
| Concurrency | Group: ci-mandatory-$, cancel-in-progress: true |
Path groups and triggered jobs
| Changed paths | detect-changes output |
Jobs triggered |
|---|---|---|
app/**, routes/**, config/**, database/**, tests/**, bootstrap/**, composer.json, composer.lock, phpunit.xml, artisan |
backend |
backend-lint, backend-tests |
resources/css/**, resources/views/**, vite.config.js, postcss.config.js, package.json, package-lock.json, tsconfig.json |
root-frontend |
backend-rendered-frontend-validation |
scripts/importer/** |
importer |
importer-validation |
scripts/importer/package.json, scripts/importer/package-lock.json, scripts/import-tool/Dockerfile, scripts/import-tool/entrypoint.sh |
import-tool-image |
import-tool-image |
scripts/site-i18n/** |
site-i18n |
site-i18n-validation |
scripts/parity/** |
parity |
parity-validation |
scripts/data-packages-mcp/** |
data-packages-mcp |
data-packages-mcp-validation |
scripts/exporters/** |
exporters |
exporter-validation |
scripts/viewers/** |
viewers |
viewer-validation |
dependency-review and php-version-drift have no path gate: they run on every pull request.
Jobs
- detect-changes (Detect Changed Paths) - Classifies changed files using
git diffagainst the PR base SHA- Checks out the repository with full Git history (
fetch-depth: 0) - Emits outputs:
backend,root-frontend,importer,import-tool-image,site-i18n,parity,data-packages-mcp,exporters,viewers(true/false) - Also emits
exporter-datasetsandviewer-datasets, JSON arrays of every directory underscripts/exporters/andscripts/viewers/holding apackage.json, used as theexporter-validationandviewer-validationmatrices
- Checks out the repository with full Git history (
- dependency-review (Dependency Review (PR)) - Reviews dependency changes introduced by the pull request
- Runs
actions/dependency-review-actionwithfail-on-severity: high - Has no
needsand no path gate — it always runs
- Runs
- php-version-drift (PHP Version Drift Check) - Checks that the three places naming the PHP version agree
- Compares the major.minor of
composer.jsonconfig.platform.php, theFROM php:tag of.docker/Dockerfileand thephp-versiondefault of thesetup-backendaction - Fails when one of them cannot be read, or when they differ
- Has no
needsand no path gate — a version can drift through a Dockerfile-only or action-only edit that no path group watches
- Compares the major.minor of
- backend-lint (when
backend=true) (Backend Linting and Validation) - Laravel backend linting- Uses the
setup-backendcomposite action withtools: pint(PHP 8.5, Composer install,.envfrom.env.local.example,php artisan migrate) - Runs against SQLite in memory (
DB_CONNECTION=sqlite,DB_DATABASE=:memory:) - Runs
composer check-platform-reqs - Runs
./vendor/bin/pint --bail
- Uses the
- backend-tests (when
backend=true) (Backend Tests (<suite>)) - Laravel test matrix- Uses the
setup-backendcomposite action withtools: phpunit, pestandcoverage: xdebug - Matrix:
Unit,Api,Filament,Configuration,Console,Event,Integration fail-fast: true— stops remaining suites on first failure- Runs each suite with
php artisan test --testsuite=<suite> --coverage --parallel --no-ansi --stop-on-failure
- Uses the
- backend-rendered-frontend-validation (when
root-frontend=true) (Filament Theme Build) - Builds the admin panel’s Tailwind theme, the only front-end asset- Uses the
setup-node-projectcomposite action at the repository root - Runs
npm run build
- Uses the
- importer-validation (when
importer=true) (Importer Validation (TypeScript)) - Importer TypeScript build and tests- Uses the
setup-node-projectcomposite action withworking-directory: scripts/importer - Runs
npm run build(TypeScript compilation) - Runs
npm test(Vitest unit tests)
- Uses the
- import-tool-image (when
import-tool-image=true) (Import Tool Image Build) - Builds the Alpine import-tool image- Narrower than the
importergroup on purpose: only a dependency change or an edit to the image’s own files can breakdocker build, typically a native module with no musl prebuild - Runs
docker buildofscripts/import-tool/Dockerfile, then smoke-tests the image with the importer CLI’simport --help, which needs no database - Builds only: nothing is tagged for a registry or pushed
- Narrower than the
- site-i18n-validation (when
site-i18n=true) (Site i18n Validation (TypeScript)) - Shared site i18n layer validation- Uses the
setup-node-projectcomposite action withworking-directory: scripts/site-i18n - Runs
npm run lint:check,npm run buildandnpm test - Every test in this suite is a pure function over legacy row shapes, so no database, VPN or credentials are involved
- Uses the
- parity-validation (when
parity=true) (Parity Tool Validation) - The legacy parity tool- Uses the
setup-node-projectcomposite action withworking-directory: scripts/parity - Runs
npm run lint:checkandnpm test(the gate tests) - The comparison itself never runs here: it reads the live legacy sites and a local cache of their answers. See
scripts/parity/README.md
- Uses the
- data-packages-mcp-validation (when
data-packages-mcp=true) (Data Packages MCP Validation) - The read-only MCP server over the published data packages- Uses the
setup-node-projectcomposite action withworking-directory: scripts/data-packages-mcp - Runs
npm run type-check,npm run lint:checkandnpm test, then builds the server image (docker build --target server) - Every test runs against fixture packages and a mocked registry, so no network, registry or credentials are involved
- Uses the
- exporter-validation (when
exporters=true) (Exporter Validation (<dataset>)) - Dataset exporter validation- Matrix comes from
detect-changes’sexporter-datasetsoutput, not a hardcoded list — a forked exporter is covered from its first pull request fail-fast: false— every dataset is reported, even when one fails- Uses the
setup-node-projectcomposite action withworking-directory: scripts/exporters/<dataset> - Runs
npm run type-check,npm run lint:checkandnpm test(Vitest unit tests) - Every test in these suites is a pure function over legacy row shapes, so no database, VPN or credentials are involved
- Matrix comes from
- viewer-validation (when
viewers=true) (Viewer Validation (<viewer>)) - Dataset viewer build- Matrix comes from
detect-changes’sviewer-datasetsoutput, not a hardcoded list fail-fast: false— every viewer is reported, even when one fails- Uses the
setup-node-projectcomposite action withworking-directory: scripts/viewers/<viewer> - Runs
npm run build -- --base=/<viewer>/, the base path the deploy workflow uses - Installs the viewer’s public
@museumwnf/<site>-datapackage from npmjs, so a viewer whose package is not published fails here, as it could not be deployed either
- Matrix comes from
- ci-success (CI Success) - Aggregates all check results
needsevery other job and runs withif: always()- Always requires
dependency-reviewandphp-version-driftto have succeeded - For each path group that changed, requires the matching job(s) to have succeeded
- When a path group did not change, its job may be skipped without failing the workflow
- This job name satisfies the
CI Successbranch protection required check
Permissions
contents: read- For reading repository contents
Branch protection
The CI Success job in this workflow satisfies the CI Success required status check configured in branch protection rules for main. Dependency review and the PHP version drift check must always pass; the path-gated lint/build/test jobs must pass whenever their path group changed.
Usage
This workflow runs automatically on pull requests. Skipped jobs are expected when their path group has no changed files — a skipped job is a pass, and ci-success only requires a job whose path group actually changed.
There is no manual trigger: CI exists to gate a pull request, and both dependency-review and path detection are defined only in that context. To re-run it, push to the branch or use Re-run all jobs on the existing run.
Dependency Audit (Full Tree)
Audits the full dependency tree of every PHP and npm project in the repository on a weekly schedule, and opens (or comments on) a tracking issue when vulnerabilities are found. Dependency changes on a pull request are handled by the dependency-review job of the CI workflow instead.
Workflow properties
| Property | Value |
|---|---|
| Workflow | dependency-audit.yml |
| Workflow name | Dependency Audit (Full Tree) |
| Trigger | Schedule — 0 6 * * 1 (every Monday at 06:00 UTC) |
| Manual trigger | Yes (workflow_dispatch) |
| Runner | ubuntu-latest (GitHub-hosted) |
| Concurrency | Group: dependency-audit, cancel-in-progress: true |
Jobs
- audit-composer (Audit - Composer (PHP)) - Audits PHP/Composer dependencies
- Installs PHP 8.5 with extensions
- Installs Composer dependencies
- Runs
composer audit
- enumerate-npm-projects (Enumerate npm Projects) - Builds the
audit-npmmatrix from the checkout- Finds every
package.jsonin the tree (excludingnode_modules) and emitsprojects: a JSON array of{name, directory}objects. Every project resolves from the public npm registry, so noregistryfield is needed - No project or directory is named in this workflow — a new tool under
scripts/, or a forked exporter or viewer, is audited from the day it lands with no edit here..github/dependabot.ymlcovers the same directories by glob, so the two agree by construction
Contributes Root(.)Importer(scripts/importer)Site i18n(scripts/site-i18n)Data packages MCP(scripts/data-packages-mcp)Exporter (<dataset>), perpackage.jsonunderscripts/exporters/*/Viewer (<dataset>), perpackage.jsonunderscripts/viewers/*/any other package.jsonunderscripts/Both sides read the tree. This matrix finds every
package.json;.github/dependabot.ymlcovers the same directories withdirectories:globs. “Gets a weekly audit” and “gets dependency updates” are therefore the same set by construction — not because a check compares two hand-written lists, but because neither list is hand-written.This job previously hand-listed
Root,SPAandImporterand globbed onlyscripts/exportersandscripts/viewers.scripts/site-i18nmatched none of those and received no weekly audit at all from the day it landed — which is why it now enumerates rather than enumerates-and-verifies. - Finds every
- audit-npm (Audit - npm (
<name>)) - Audits every npm project, as a single matrix job- Matrix:
fromJSONofenumerate-npm-projects’sprojectsoutput fail-fast: false— every directory is audited even if one fails- Uses the
setup-node-projectcomposite action per matrix entry, with that entry’s registry - Runs
npm audit --audit-level highin each directory
- Matrix:
- report (Report Failures) - Reports vulnerabilities as an issue
needs: [audit-composer, enumerate-npm-projects, audit-npm], runs withif: always()when any of them failed- Opens an issue titled
Weekly dependency audit found vulnerabilitieswith thedependencieslabel, or comments on the existing open one
Permissions
contents: read- For reading repository contentsissues: write- For opening or commenting on the tracking issue
Usage
This workflow runs automatically every Monday. For manual triggering:
Actions > Dependency Audit (Full Tree) > Run workflow
Continuous Deployment
Build
Builds the Laravel application, packages it, publishes a GitHub pre-release, and uploads the deployment tarball consumed by Deploy to OVH.
Workflow properties
| Property | Value |
|---|---|
| Workflow | build.yml |
| Workflow name | Build |
| Trigger | Push to main branch, or push of a v*.*.* tag |
| Manual trigger | Yes (workflow_dispatch) |
| Runner | ubuntu-latest (GitHub-hosted) |
| Environment | MWNF-SVR |
| Concurrency | Group: cd-$, cancel-in-progress: true |
Job: build (Build and Package Application)
- Installs PHP 8.5 (matching
.docker/Dockerfileand the VPS) with Pint, and Node.jslts/Krypton - Installs PHP dependencies with
composer install --no-dev --optimize-autoloader - Publishes Filament assets (
php artisan filament:assets) - Installs and builds the backend assets with Vite (
npm ci,npm run build) - Validates that
public/build,public/css/filamentandpublic/js/filamentexist - Creates the deployment package and a
VERSIONfile (app version, commit SHA, build number, timestamps) - Produces both
inventory-app.zipandrelease.tar.gz - Generates the release tag
<package.json version>.<run_number> - Creates a GitHub pre-release with
inventory-app.zipattached - Uploads the artifact
release-$(containingrelease.tar.gz) with 7-day retention
Permissions
contents: write- For creating releases
Usage
This workflow runs automatically when changes are pushed to main. It is the upstream of Deploy to OVH.
Deploy to OVH
Deploys the tarball produced by Build to the OVH VPS over SSH, by running scripts/deploy.sh on the server.
Workflow properties
| Property | Value |
|---|---|
| Workflow | deploy-ovh.yml |
| Workflow name | Deploy to OVH |
| Trigger | workflow_run — after the Build workflow completes on main |
| Manual trigger | Yes (workflow_dispatch) — optional run_id input; defaults to the latest successful Build run on main |
| Runner | ubuntu-24.04 (GitHub-hosted) |
| Environment | inventory.metanull.eu (https://inventory.metanull.eu) |
| Concurrency | Group: deploy-ovh, cancel-in-progress: false |
Job: deploy (Deploy to OVH VPS)
- Only runs when triggered manually, or when the upstream
Buildrun concludedsuccess - Resolves the
Buildrun id and head SHA, then downloads therelease-<sha>artifact from it - Checks out that same head SHA, not
main’s HEAD, soscripts/deploy.shalways comes from the commit the artifact was built from. Two merges close together would otherwise pair a newer script with an older release - Verifies
release.tar.gzis present, and that the checked-out commit and thecommit_shain the artifact’sVERSIONfile both match the Build run’s head SHA; on a mismatch it fails before anything reaches the VPS - Sets up the SSH key, checks TCP reachability of port 22, and verifies SSH authentication (up to 3 attempts with backoff, failing fast on an auth rejection)
- Uploads
release.tar.gzandscripts/deploy.shto the VPS, then runs the deploy script - The script ends with a smoke check, over HTTPS on the server itself:
/must redirect to/adminand/admin/loginmust answer 200, or the job fails - Cleans up the uploaded files on the VPS (
if: always())
Permissions
contents: read- For reading repository contentsactions: read- For listing and downloading artifacts from theBuildrun
Secrets
| Secret | Description |
|---|---|
VPS_HOST |
Hostname or IP of the OVH VPS |
VPS_SSH_USER |
SSH user used for deployment |
VPS_SSH_KEY |
Private SSH key for that user |
Deploy Documentation to GitHub Pages
Generates and deploys the Jekyll-based static documentation website to GitHub Pages. This workflow calls a Python script to generate commit history documentation.
See /docs/README.md for complete Jekyll site documentation.
Workflow properties
| Property | Value |
|---|---|
| Workflow | continuous-deployment_github-pages.yml |
| Workflow name | Documentation |
| Trigger | Push to main branch |
| Manual trigger | Yes (workflow_dispatch) |
| Runner | ubuntu-latest (GitHub-hosted) |
| Concurrency | Group: pages-deploy, cancel-in-progress: true |
Jobs
- build - Generates and builds documentation
- Checks out repository with full Git history (
fetch-depth: 0) - Sets up Python 3.x
- Sets up Ruby (working directory
docs). The version lives in the workflow itself; keep it in step with.docker/Dockerfile.docsanddocs/Gemfile - Installs Ruby dependencies with
bundle install - Generates commit history documentation - Calls
python scripts/generate-commit-docs.py. See /scripts/README.md - Builds Jekyll site with
bundle exec jekyll build - Uploads
docs/_siteas the GitHub Pages artifact
- Checks out repository with full Git history (
- deploy (needs
build) - Deploys to GitHub Pages- Uses
actions/deploy-pagesto publish the site - Sets environment to
github-pages - Outputs deployment URL
- Uses
Permissions
contents: read- For reading repository contents (workflow default)contents: write- Overridden on thebuildjob, for committing generated documentationpages: write- For deploying to GitHub Pagesid-token: write- For GitHub Pages authentication
Scripts called
This workflow depends on the following script:
generate-commit-docs.py- Converts Git commit history into Jekyll markdown pages. See /scripts/README.md
For Jekyll site documentation, see /docs/README.md
Usage
This workflow runs automatically on push to main. For manual deployment:
# Trigger via GitHub UI: Actions > Documentation > Run workflow
Links
| Reference | URL |
|---|---|
| GitHub Pages | https://pages.github.com/ |
| Documentation Site | https://museumwithnofrontiers.github.io/inventory-app |
| Jekyll Documentation | https://jekyllrb.com/docs/ |
Deploy Dataset Viewers to OVH
One workflow per dataset viewer. Each builds its Vite viewer against the latest published @museumwnf/<dataset>-data package and copies the build output to the OVH VPS over SSH.
Workflows
| Dataset | Workflow | Path filter | Vite base | Target directory | URL |
|---|---|---|---|---|---|
baroqueart |
deploy-viewer-baroqueart-ovh.yml |
scripts/viewers/baroqueart/** |
/baroqueart/ |
/opt/baroqueart/ |
https://inventory.metanull.eu/baroqueart/ |
islamicart |
deploy-viewer-islamicart-ovh.yml |
scripts/viewers/islamicart/** |
/islamicart/ |
/opt/islamicart/ |
https://inventory.metanull.eu/islamicart/ |
sharinghistory |
deploy-viewer-sharinghistory-ovh.yml |
scripts/viewers/sharinghistory/** |
/sharinghistory/ |
/opt/sharinghistory/ |
https://inventory.metanull.eu/sharinghistory/ |
amulets |
deploy-viewer-amulets-ovh.yml |
scripts/viewers/amulets/** |
/amulets/ |
/opt/amulets/ |
https://inventory.metanull.eu/amulets/ |
carpets |
deploy-viewer-carpets-ovh.yml |
scripts/viewers/carpets/** |
/carpets/ |
/opt/carpets/ |
https://inventory.metanull.eu/carpets/ |
Workflow properties (identical apart from the dataset name)
| Property | Value |
|---|---|
| Trigger | Push to main limited to the viewer’s own path filter |
| Manual trigger | Yes (workflow_dispatch) |
| Runner | ubuntu-latest (GitHub-hosted) |
| Environment | inventory.metanull.eu |
| Concurrency | Group: deploy-viewer-<dataset>-ovh, cancel-in-progress: false |
Job: build-and-deploy (Build and Deploy <dataset> Viewer)
- Sets up Node.js
lts/Krypton(no registry scoping needed — the data package is public on npmjs) - Installs viewer dependencies with
npm ci - Runs
npm install @museumwnf/<dataset>-data@latest— the newest data package is always pulled, regardless of whatpackage-lock.jsonpins, so the viewer reflects current data - Builds with
npm run build -- --base=/<dataset>/ - Sets up SSH, checks VPS connectivity and verifies SSH authentication
- Copies
dist/to the target directory on the VPS withscp - Removes the SSH key (
if: always())
Permissions
contents: read- For reading repository contents.@museumwnf/<dataset>-datais public on npmjs, so nopackages: readpermission is needed here.
Secrets
| Secret | Description |
|---|---|
VPS_HOST |
Hostname or IP of the OVH VPS |
VPS_SSH_USER |
SSH user used for deployment |
VPS_SSH_KEY |
Private SSH key for that user |
Automation Workflows
Dependabot Configuration
Dependabot is configured in .github/dependabot.yml to keep dependencies up to date across the repository.
Node projects under
scripts/are covered by glob. Adding a forked exporter, a new viewer or a new tool needs no change to.github/dependabot.yml— it lands inside one of thedirectories:patterns and is picked up on the next run.
Ecosystems monitored
| Ecosystem | Directories | Schedule | Registry |
|---|---|---|---|
composer |
/ |
Weekly | packagist.org (public) |
npm |
/ |
Weekly | registry.npmjs.org (public) |
npm |
/scripts/* |
Weekly | registry.npmjs.org (public) |
npm |
/scripts/exporters/* |
Weekly | registry.npmjs.org (public) |
npm |
/scripts/viewers/* |
Weekly | registry.npmjs.org (public) |
github-actions |
/ |
Weekly | github.com (public) |
/scripts/* is one level deep on purpose: scripts/exporters and scripts/viewers hold no manifest of their own, and their children are matched by the two patterns below it.
No entry carries a registries: key. Every npm project resolves from the public registry — the viewers install @museumwnf/<dataset>-data from npmjs like everything else — so no entry needs a credential, and a new project inherits the right answer from where its directory lives rather than from a reviewer noticing.
One pull request per directory. A glob does not couple the projects it matches: Dependabot’s default for a multi-directory entry is a separate PR per directory, so a failing bump in one exporter does not block the others. Setting group-by: dependency-name on a group would collapse them into a single cross-directory PR — avoid that unless PR volume ever becomes the problem.
History. This file used to carry one hand-written entry per project (20 in all), policed by a blocking
Dependabot Coveragejob runningscripts/check-dependabot-coverage.sh. That machinery existed because Dependabot config was believed unable to enumerate directories — true when it was written, but thedirectories:key with glob support shipped in June 2024. The hand-maintenance had already failed twice in practice (scripts/viewers/amuletsin PR #1566, patched in #1572), and the check never caught the one real outage — every viewer’s job aborted for months over a missing registryscope(#1609) while the coverage check passed, because it validated the config’s shape rather than whether the job ran. Both the script and the gate were removed once the globs replaced them.
Links
| Reference | URL |
|---|---|
| Dependabot configuration options | https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file |
Merge Dependabot PR
Automatically approves and enables auto-merge for eligible Dependabot pull requests.
Workflow properties
| Property | Value |
|---|---|
| Workflow | merge-dependabot-pr.yml |
| Workflow name | Dependabot Auto-Merge |
| Trigger | pull_request_target (any PR activity) |
| Manual trigger | No |
| Runner | ubuntu-latest (GitHub-hosted) |
| Condition | Only runs if PR author is dependabot[bot] |
Job: dependabot
- Fetches Dependabot PR metadata using the
dependabot/fetch-metadataaction - Determines auto-merge eligibility from the package ecosystem and update type
- Approves eligible PRs using
gh pr review --approve - Enables auto-merge on eligible PRs using
gh pr merge --auto --squash
Permissions
pull-requests: write- For approving and merging PRscontents: write- For merging changes
Behavior
github_actionsecosystem: Auto-merged at any semver level, including major — Actions bumps only touch the CI pipeline, never shipped application code, and a broken one fails the same PR’s required checks immediately- Application dependencies (npm/composer), minor and patch updates: Automatically approved and enabled for auto-merge
- Application dependencies (npm/composer), major updates: Require manual review (not auto-approved)
Usage
This workflow runs automatically when Dependabot opens a pull request. No manual intervention is needed for eligible updates.
Links
| Reference | URL |
|---|---|
| Dependabot | https://docs.github.com/en/code-security/dependabot |
| dependabot/fetch-metadata | https://github.com/dependabot/fetch-metadata |
Composite Actions
Repeated setup and publishing steps live in .github/actions and are referenced from workflows with uses: ./.github/actions/<name>.
| Action | Purpose | Key inputs / outputs | Used by |
|---|---|---|---|
setup-backend |
Installs PHP (default 8.5) with the project’s extensions, installs Composer dependencies, creates .env from .env.local.example, generates the app key and migrates the database |
Inputs: php-version, tools, coverage |
continuous-integration.yml |
setup-node-project |
Installs Node.js lts/Krypton, enables Corepack and runs npm ci in a given directory |
Inputs: working-directory, registry-url, node-auth-token |
continuous-integration.yml, dependency-audit.yml |
Workflow Dependencies
Several workflows interact with scripts, composite actions and other workflows:
| Workflow | Depends On | Triggers |
|---|---|---|
continuous-integration.yml |
setup-backend, setup-node-project |
- |
dependency-audit.yml |
setup-node-project |
- |
build.yml |
- | deploy-ovh.yml (via workflow_run) |
deploy-ovh.yml |
build.yml artifact, scripts/deploy.sh |
- |
continuous-deployment_github-pages.yml |
/scripts/README.md scripts | - |
deploy-viewer-*-ovh.yml |
@museumwnf/<dataset>-data on npmjs (public) |
- |
merge-dependabot-pr.yml |
- | - |
Scripts used by workflows:
generate-commit-docs.py- Used bycontinuous-deployment_github-pages.yml. See /scripts/README.mddeploy.sh- Uploaded to the VPS and executed bydeploy-ovh.yml. See /scripts/README.md
Contributing
When adding new workflows:
- Add description to this README
- Document triggers, jobs, permissions, and environment variables
- Update the workflow dependencies table
- Add cross-references to /scripts/README.md if applicable
- Test both manual and automated execution
- Validate workflow syntax with
node scripts/validate-workflows.cjs. See /scripts/README.md