Skip to content

coroboros/ci

Repository files navigation

Coroboros

coroboros/ci

Reusable GitHub Actions CI for the Coroboros stack.

Drop into any @coroboros/* repo via uses: coroboros/ci/.github/workflows/<name>.yml@v0, or compose around the composite actions under .github/actions/.

latest ci branch license stars skills coroboros.com

Imposed, not proposed. Pipelines expose zero inputs: — same install flags, same publish auth, same security baseline across every Coroboros repo. Consumers wire it in.


Pipelines

javascript-npm-packages.yml

Bundled NPM CI.

Consumer requirements:

  • .node-version
  • package.json with
    • packageManager: "pnpm@X.Y.Z", scripts.lint, scripts.test.
    • scripts.build is optional (auto-detected).
  • pnpm-lock.yaml — required for --frozen-lockfile.
preflight

Trigger: branch push

Sequence:

  1. Checkout
  2. Run check-docs
  3. Run javascript/base
publish

Trigger: tag push

Sequence:

  1. Checkout main with full history
  2. Verify main HEAD matches the tag SHA
  3. Run check-docs
  4. Run javascript/base
  5. Pin package.json version to the tag
  6. Generate CHANGELOG.md section via release/generate-changelog
  7. Publish to npm — OIDC + provenance or token-based via .npmrc (see Security)
  8. Create GitHub Release via release/github-release
  9. Commit release artifacts back to main as chore: release ${tag}
  10. Move rolling major tag vN to the release commit (skipped on pre-release tags)
security

Trigger: every call

Calls security.yml — see Security.

security.yml

Reusable sub-workflow with three parallel scans:

  • gitleaks — Installs v8.30.1 (SHA-256 verified), scans git history with the security/.gitleaks.toml ruleset, fails on detected leaks. Emits SARIF as the gitleaks-report artifact (30-day retention).
  • dependency-review — PR-only; needs repo's Dependency graph enabled. Fails on high-severity CVE introduced by the dep diff. Uses actions/dependency-review-action@v4.
  • osv-scanner — Scans lockfiles recursively against OSV.dev via google/osv-scanner-action@v2. Fails on any known vulnerability.

Imposed on every Coroboros workflow. Standalone wire-up — see Examples.


Notes — pin via @v0 (rolling major, auto-bumped on each release) or @x.y.z (immutable). Pipelines don't chain via needs:; the only sub-workflow call is securitysecurity.yml.


Composable actions

Action Type Purpose
check-docs transverse Context dump + documentation check.
javascript/base JavaScript Sets up Node + corepack pnpm, caches the store, writes .npmrc from env, then installs, lints, builds (when present), tests.
release/generate-changelog transverse SemVer-strict tag guard + generates or reuses the ## vX.Y.Z section in CHANGELOG.md from Conventional Commits. Outputs body. Idempotent.
release/github-release transverse Creates the GitHub Release for the current tag. Body typically chained from release/generate-changelog (see Examples).

Development flow

Develop with Conventional Commits → tag → push. No manual CHANGELOG, no version bump.

Tags follow SemVer strict1.2.3, never v1.2.3.

Branch models

main-only — feature branch → PR → squash-merge to main → tag the merge commit → push.

develop + main — PR into develop → tag → release/x.y.z branch → merge to mainmain reflects production.

Nobody pushes directly to protected branches (main, develop, release/x.y.z).

Conventional Commits → CHANGELOG
Commit type CHANGELOG subsection
feat Features
fix Fixes
refactor Refactor
perf Performance
docs Documentation
chore / ci / build Configuration
test Tests
style Style
Other / non-standard Others
!: or BREAKING CHANGE: Breaking Changes (always first)

Section format: ## vX.Y.Z - DD/MM/YYYY. Idempotent. Reuses an existing hand-curated section for the tag if present.


Environment

Zero inputs on pipelines and on every composite — imposed, not proposed. Configuration flows through secrets: and the caller's vars context.

Secrets (caller's secrets: block)
name required description
NPM_CONFIG_FILE .npmrc content. Written to repo root by javascript/base. ${VAR} references inside are expanded by npm at install time.
NPM_EXTRA_CONFIG Extra .npmrc lines appended after NPM_CONFIG_FILE. A secret — it lands in .npmrc, so it can carry auth material and must stay masked.
NPM_PACKAGE_REGISTRY npm package registry URL.
NPM_PACKAGE_PROXY_REGISTRY Optional npm proxy registry URL.
NPM_PACKAGE_REGISTRY_TOKEN Required for token-based publish to private registries. Absent → OIDC.
javascript/base env contract (standalone composition)
env required description
NPM_CONFIG_FILE ✔ — fail if missing .npmrc content
NPM_EXTRA_CONFIG Appended after NPM_CONFIG_FILE

Set both at the caller's workflow- or job-level env:.

release/* composites I/O

release/generate-changelog — no inputs, no secrets. Reads GITHUB_REF_NAME. Requires fetch-depth: 0 for git describe. Output:

output description
body CHANGELOG section body — use as release notes.

release/github-release — input:

input required description
body Release notes body, typically steps.<id>.outputs.body from release/generate-changelog.

Caller job needs permissions: contents: write. Uses ${{ github.token }} internally via GH_TOKEN.


Security

Supply chain — pnpm install flags

pnpm install --frozen-lockfile --ignore-scripts runs inside javascript/base.

  • --frozen-lockfile — fails on stale or tampered pnpm-lock.yaml. Gate against transitive-dependency injection.
  • --ignore-scripts — skips lifecycle scripts (preinstall, install, postinstall) of every dependency. Cuts the postinstall supply-chain vector.

pnpm CLI resolved via corepack from packageManager. No floating version reaches the runner.

Publish — OIDC vs token auth

Auto-detected by NPM_PACKAGE_REGISTRY_TOKEN presence:

  • Absentpnpm publish --provenance --no-git-checks (OIDC Trusted Publisher + provenance attestation, no long-lived token).
  • Presentpnpm publish --no-git-checks (token-based via the .npmrc generated by javascript/base).
Secret isolation

Each workflow_call.secrets: block declares ONLY the secrets the job consumes. No secrets: inherit anywhere.

Action pinning + Dependabot

Third-party actions across workflows + composites are pinned to a commit SHA with an inline # vX comment. Floating refs (@master, @main, @vX) are banned.

Self-CI binaries pinned by version. actionlint and gitleaks install from release tarballs with SHA-256 verification; yamllint via pip install with version pin. No curl | bash.

.github/dependabot.yml opens weekly grouped auto-PRs to bump pinned SHAs across .github/workflows/* and .github/actions/**/action.yml. Consumers should add their own ecosystem entries (e.g., npm).

Canonical gitleaks config

Canonical ruleset at security/.gitleaks.toml in this repo. Stack-specific rules cover Resend, Neon Postgres, PostHog, and GitHub fine-grained PATs on top of the gitleaks defaults.

security.yml sparse-checks the file out of coroboros/ci at runtime — imposed, no consumer override.


Examples

javascript-npm-packages.yml wire-up
# consumer-repo/.github/workflows/ci.yml
name: CI
on:
  push:
    branches: [develop, main]
    tags: ['*']
  pull_request:
  workflow_dispatch:

jobs:
  ci:
    uses: coroboros/ci/.github/workflows/javascript-npm-packages.yml@v0
    permissions:
      contents: write   # GitHub Release on tag
      id-token: write   # npm OIDC publish on tag
    secrets:
      NPM_CONFIG_FILE: ${{ secrets.NPM_CONFIG_FILE }}
      NPM_PACKAGE_REGISTRY: ${{ secrets.NPM_PACKAGE_REGISTRY }}
      NPM_PACKAGE_PROXY_REGISTRY: ${{ secrets.NPM_PACKAGE_PROXY_REGISTRY }}
      NPM_PACKAGE_REGISTRY_TOKEN: ${{ secrets.NPM_PACKAGE_REGISTRY_TOKEN }}
security.yml standalone (non-npm repo)
# consumer-repo/.github/workflows/security.yml
name: Security
on:
  push:
    branches: [develop, main]
  pull_request:
  schedule:
    - cron: '0 0 * * 0'   # weekly — catches CVEs published after last push

permissions:
  contents: read

jobs:
  scan:
    uses: coroboros/ci/.github/workflows/security.yml@v0
Compose with javascript/base
jobs:
  custom:
    runs-on: ubuntu-latest
    permissions:
      contents: read
    env:
      NPM_CONFIG_FILE: ${{ secrets.NPM_CONFIG_FILE }}
      NPM_EXTRA_CONFIG: ${{ secrets.NPM_EXTRA_CONFIG }}
    steps:
      - uses: actions/checkout@v4
      - uses: coroboros/ci/.github/actions/check-docs@v0
      - uses: coroboros/ci/.github/actions/javascript/base@v0
      - run: pnpm run my-custom-script
        shell: bash
Compose a custom release pipeline (non-npm artifact)
jobs:
  publish:
    if: ${{ github.ref_type == 'tag' }}
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4
        with:
          ref: main
          fetch-depth: 0
      - id: changelog
        uses: coroboros/ci/.github/actions/release/generate-changelog@v0
      # ...your publish step (docker push, gh release upload, etc.)...
      - uses: coroboros/ci/.github/actions/release/github-release@v0
        with:
          body: ${{ steps.changelog.outputs.body }}

License

All Rights Reserved. See LICENSE.md.

Packages

 
 
 

Contributors