Writing a package
Adding a new workflow
Create the workflow directory.
mkdir workflows/<name>Add the workflow YAML file, named
<name>.yml(or<name>.yaml).Follow the naming convention used by
super-linter: the filename must match the directory name.Add
workflow.ymlinside the workflow directory.This file declares which packaged files the CLI installs and where they should be written in the consumer repository.
name: <name> files: - source: <name>.yml target: .github/workflows/<name>.ymlAdd
package.jsoninside the workflow directory.{ "name": "@ghwfxlab/ghwm-<name>", "version": "1.0.0", "files": ["<name>.yml", "workflow.yml"], "publishConfig": { "registry": "https://npm.pkg.github.com" } }Add a
README.mdinside the workflow directory. It must cover at minimum:- What the workflow does (one-paragraph summary)
- What gets installed in the consumer repository
- Consumer setup steps (secrets, variables, permissions)
- How to trigger the workflow
- How to update and remove the workflow
- Known limitations or caveats
Register the workflow in both index files:
workflows/README.md— add a row to the Available Workflows tableREADME.md— add a row to the Available Workflows table
The root
package.jsonalready includesworkspaces: ["workflows/*"], so new workflow directories are picked up automatically.Open a pull request and request review from a maintainer.
Updating an existing workflow
- Edit the workflow YAML,
workflow.yml,package.json, and/or itsREADME.mdas needed. - Bump
workflows/<name>/package.jsonwhen the change should ship to consumers. - If inputs, outputs, secrets, permissions, or packaged config files changed, update the readme accordingly.
- Remember that consumer repositories control update behaviour in
ghwm.yml:update-triggers: true|falsedecides whether workflow updates replace the installedon:section or preserve the repository's current trigger configuration.update-config-files: true|falsedecides whether workflow updates replace packaged config files or leave the existing checked-in copies untouched.
Development setup
Prerequisites: Git, Node.js ≥ 18 (for textlint), Python ≥ 3.9 (for pre-commit), Docker (for super-linter).
make setup-precommit
# Verify everything is wired up
make precommitQuality checks
| Command | What it does |
|---|---|
make lang |
Lint prose (terminology, style) with textlint |
make lang-fix |
Autofix textlint violations |
make script-tests |
Run unit tests for repository helper scripts |
make precommit |
Run all pre-commit hooks on every file |
make super-linter |
Full lint pass (YAML, Markdown, Actions) via Docker |
make super-linter-fix |
Full lint pass with autofix via Docker |
Run make lang and make precommit before pushing. CI runs the same checks automatically.
The pre-commit hook also runs make script-tests automatically on every commit.
Pull request guidelines
- Use a descriptive title following Conventional Commits (e.g.
feat(super-linter): add RUN_SUPER_LINTER_SLIM variable docs). - Fill in the pull request template.
- Keep each PR focused on a single workflow or concern.
- Ensure
make langpasses with no errors. - Do not push directly to
main; all changes go through pull requests.
Publishing workflow packages
Publishing is automatic on merge to main.
The publish workflow scans every workflow package under
workflows/, compares the version in package.json to GitHub Packages, and publishes only the
packages whose version is new.
Version management uses two safeguards:
- The local pre-commit hook checks staged workflow package content against the latest published
package version. If the staged package content changed and the local version is not ahead of the
published version, it patches
package.jsonto the next patch version, stages the file, prints the change, and stops the commit so you can review it and rerungit commit. - Pull request CI repeats the same comparison for changed published package content and adds a pull request comment if any changed workflow package still needs a version bump.
The automation only considers published package content: package.json plus the paths listed in
the workflow package files array. Workflow-specific readme-only changes do not trigger a version
bump because the readme is not shipped in the npm package.
If you want a minor or major release, bump the workflow package version in
workflows/<name>/package.json yourself before committing so the automation does not replace it
with a patch bump.
Use semantic versioning:
- Patch — bugfixes, documentation corrections, no behaviour change
- Minor — new optional inputs, additive features, new packaged config files
- Major — breaking changes (renamed files, removed inputs, permission changes, changed default triggers)
Dependency maintenance with Renovate
The repository runs an automated Renovate workflow daily at 03:00 UTC (and on manual trigger via workflow_dispatch).
What Renovate manages
- Pinned GitHub Actions digests in
workflows/** - Dependencies in
.pre-commit-config.yaml - Pinned Docker image digests in
Makefile(such as Super-Linter)
Automated package version bumps
When Renovate upgrades an action dependency inside a workflow file (under workflows/<name>/), a post-upgrade task automatically runs scripts/bump_renovate_packages.sh to bump the patch version in the corresponding workflow package's package.json. This ensures that downstream consumers receive the updated workflow dependencies when merged to main.
Repository requirements
To operate Renovate in GitHub Actions:
RENOVATE_TOKENrepository secret configured with a personal access token (PAT) or GitHub App token that hascontents: write,pull-requests: write, andworkflows: writepermissions.- In Settings → Actions → General → Workflow permissions, the option "Allow GitHub Actions to create and approve pull requests" must be enabled.
Rendered from ghwfxlab/ghwm-registry. View source on GitHub