Writing a package

Adding a new workflow

  1. Create the workflow directory.

    mkdir workflows/<name>
  2. 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.

  3. Add workflow.yml inside 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>.yml
  4. Add package.json inside the workflow directory.

    {
      "name": "@ghwfxlab/ghwm-<name>",
      "version": "1.0.0",
      "files": ["<name>.yml", "workflow.yml"],
      "publishConfig": { "registry": "https://npm.pkg.github.com" }
    }
  5. Add a README.md inside 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
  6. Register the workflow in both index files:

    • workflows/README.md — add a row to the Available Workflows table
    • README.md — add a row to the Available Workflows table

    The root package.json already includes workspaces: ["workflows/*"], so new workflow directories are picked up automatically.

  7. Open a pull request and request review from a maintainer.


Updating an existing workflow

  1. Edit the workflow YAML, workflow.yml, package.json, and/or its README.md as needed.
  2. Bump workflows/<name>/package.json when the change should ship to consumers.
  3. If inputs, outputs, secrets, permissions, or packaged config files changed, update the readme accordingly.
  4. Remember that consumer repositories control update behaviour in ghwm.yml:
    • update-triggers: true|false decides whether workflow updates replace the installed on: section or preserve the repository's current trigger configuration.
    • update-config-files: true|false decides 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 precommit

Quality 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


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 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:


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

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:

Rendered from ghwfxlab/ghwm-registry. View source on GitHub