Publish Packages workflow (decaporg/decap-cms)
The Publish Packages workflow from decaporg/decap-cms, explained and optimized by Latchkey.
CI health: D - needs work
Point runs-on at Latchkey and get caching, run de-duplication, job timeouts, self-healing for flaky steps, and up to 58% lower cost, applied automatically.
What it does
This is the Publish Packages workflow from the decaporg/decap-cms repository, a real project running GitHub Actions. It is shown here with attribution under its MIT license.
Below, Latchkey shows a faster, safer version produced by its optimization engine.
The workflow
name: Publish Packages
on:
push:
tags:
- 'decap-*@*'
permissions:
contents: read
id-token: write # Required for OIDC trusted publishers
jobs:
publish:
runs-on: ubuntu-latest
environment: production # Optional: adds approval requirements and deployment protection
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # Required for Lerna to detect changes
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '24'
registry-url: 'https://registry.npmjs.org'
- name: Install dependencies
run: npm ci
- name: Build packages
run: npm run build
- name: Run tests
run: npm run test:ci
- name: Test package integrity
run: npm run test:package-integrity
- name: Debug
run: |
echo "::group::Node & npm versions"
node -v
npm -v
echo "::endgroup::"
echo "::group::npm config (redacted)"
npm config get registry || true
npm config list -l | sed 's/_authToken.*/_authToken=[REDACTED]/' || true
echo "::endgroup::"
echo "::group::Env checks"
if [ -n "${NODE_AUTH_TOKEN}" ]; then echo "NODE_AUTH_TOKEN set? yes"; else echo "NODE_AUTH_TOKEN set? no"; fi
if [ -n "${NPM_CONFIG_USERCONFIG}" ]; then echo "NPM_CONFIG_USERCONFIG set? yes"; else echo "NPM_CONFIG_USERCONFIG set? no"; fi
echo "::endgroup::"
echo "::group::Git state"
git status --porcelain || true
git tag --list --points-at HEAD || true
echo "::endgroup::"
echo "::group::Registry package info"
npm view decap-server version || true
npm view decap-server versions --json || true
echo "::endgroup::"
echo "::group::Lerna packages"
npx lerna ls --json || true
echo "::endgroup::"
- name: Publish to npm
run: npm run lerna:publish -- --loglevel silly
# No NODE_AUTH_TOKEN needed - uses OIDC automatically via trusted publishers
The same workflow, on Latchkey
Estimated ~20% faster on cache hits, plus fewer wasted runs and a safer supply chain. Added and changed lines are highlighted.
name: Publish Packages on: push: tags: - 'decap-*@*' permissions: contents: read id-token: write # Required for OIDC trusted publishers concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: publish: timeout-minutes: 30 runs-on: latchkey-small environment: production # Optional: adds approval requirements and deployment protection steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 # Required for Lerna to detect changes - name: Setup Node.js uses: actions/setup-node@v4 with: cache: 'npm' node-version: '24' registry-url: 'https://registry.npmjs.org' - name: Install dependencies run: npm ci - name: Build packages run: npm run build - name: Run tests run: npm run test:ci - name: Test package integrity run: npm run test:package-integrity - name: Debug run: | echo "::group::Node & npm versions" node -v npm -v echo "::endgroup::" echo "::group::npm config (redacted)" npm config get registry || true npm config list -l | sed 's/_authToken.*/_authToken=[REDACTED]/' || true echo "::endgroup::" echo "::group::Env checks" if [ -n "${NODE_AUTH_TOKEN}" ]; then echo "NODE_AUTH_TOKEN set? yes"; else echo "NODE_AUTH_TOKEN set? no"; fi if [ -n "${NPM_CONFIG_USERCONFIG}" ]; then echo "NPM_CONFIG_USERCONFIG set? yes"; else echo "NPM_CONFIG_USERCONFIG set? no"; fi echo "::endgroup::" echo "::group::Git state" git status --porcelain || true git tag --list --points-at HEAD || true echo "::endgroup::" echo "::group::Registry package info" npm view decap-server version || true npm view decap-server versions --json || true echo "::endgroup::" echo "::group::Lerna packages" npx lerna ls --json || true echo "::endgroup::" - name: Publish to npm run: npm run lerna:publish -- --loglevel silly # No NODE_AUTH_TOKEN needed - uses OIDC automatically via trusted publishers
What changed
- Run on Latchkey managed runners with one line (
runs-on), which apply the fixes below automatically and self-heal transient failures. This example useslatchkey-small; pick the runner size that fits the job. - Cancel superseded runs when a branch or PR gets a newer push.
- Cache dependency installs on the setup step so they are served from cache.
- Add a job timeout so a hung step cannot burn hours of runner time.
What Latchkey heals here
This workflow has steps that commonly fail on transient issues (network, registries, flaky browsers). On Latchkey managed runners they are detected, retried, and self-healed instead of failing your build:
- Dependency installs
This workflow runs 1 job per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.