Communitygithub.com

Nuvraxis/nuvraxis-plugins

>- GitHub Actions conventions for Nuvraxis Next.js apps — exactly three workflows: pr.yaml (every PR to any branch: Biome, stylelint, typecheck/test/build with turbo --affected, Docker build + health check, helm lint + kubeconform; publishes nothing), main.yaml (push to main: one multi-arch image to GHCR tagged sha-SHORTSHA and main, provenance + SBOM, gha cache), release.yaml (tag vX.Y.Z: verify on main, retag the existing image without rebuilding, package and push the Helm chart to OCI, GitHub Release with chart, digest and SBOM). Minimal permissions per job, GITHUB_TOKEN only, pinned action majors. Use when editing .github/workflows/*, adding a CI step, or debugging a failed run or release.

What is nuvraxis-plugins?

nuvraxis-plugins is a Claude Code agent skill that >- GitHub Actions conventions for Nuvraxis Next.js apps — exactly three workflows: pr.yaml (every PR to any branch: Biome, stylelint, typecheck/test/build with turbo --affected, Docker build + health check, helm lint + kubeconform; publishes nothing), main.yaml (push to main: one multi-arch image to GHCR tagged sha-SHORTSHA and main, provenance + SBOM, gha cache), release.yaml (tag vX.Y.Z: verify on main, retag the existing image without rebuilding, package and push the Helm chart to OCI, GitHub Release with chart, digest and SBOM). Minimal permissions per job, GITHUB_TOKEN only, pinned action majors. Use when editing .github/workflows/*, adding a CI step, or debugging a failed run or release.

Works with~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Nuvraxis/nuvraxis-plugins/tree/HEAD/plugins/nuvraxis-frontend/skills/github-actions

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

GitHub Actions

Three workflows per app, each with one job of its kind. The template's .github/workflows/{pr,main,release}.yaml are the source of truth; they're reproduced with notes in references/workflows.md.

pull request ──► pr.yaml       checks only, nothing published
merge to main ─► main.yaml     image built once → ghcr.io/nuvraxis/<app>:sha-<short>, :main
tag vX.Y.Z ────► release.yaml  same image retagged :vX.Y.Z, :latest · chart X.Y.Z → OCI · GitHub Release

Rules for every workflow

  1. permissions: contents: read at the top; widen per job only as needed. packages: write for jobs that push to GHCR, contents: write only for the job that creates the Release. No id-token: write or attestations: write: provenance and SBOM come from BuildKit, not actions/attest* (which needs GitHub Enterprise for private repos).

  2. GITHUB_TOKEN only. GHCR login uses ${{ github.actor }} / ${{ secrets.GITHUB_TOKEN }}; gh uses GH_TOKEN: ${{ github.token }}. No personal access tokens in CI. (Pulling private packages from the cluster is a different credential; see helm-nextjs.)

  3. Pin action majors (@v7) and keep the SHA table current. The template uses major tags for readability. If the org requires SHA pinning, replace each @vN with the SHA from references/action-pins.md and keep the # vN.M.P comment. Current majors: checkout v7, setup-node v7, pnpm/action-setup v6, setup-qemu v4, setup-buildx v4, login v4, metadata v6, build-push v7, azure/setup-helm v5.

  4. Toolchain: pnpm/action-setup before actions/setup-node. action-setup reads the pnpm version from packageManager; setup-node reads .node-version and caches the pnpm store (cache: pnpm needs pnpm on PATH first). Then pnpm install --frozen-lockfile. Never npm ci.

  5. concurrency per workflow and ref; cancel in progress on PRs only. A new push to a PR cancels the old run. On main and tags runs always finish: release.yaml needs the image of that exact commit.

  6. Never echo secrets or interpolate untrusted input into run:. Pass values through env: and quote them ("${APP}"). ${{ github.event.pull_request.title }} and similar never go inside a script. persist-credentials: false on checkout when the job doesn't push to git.

  7. Every job has timeout-minutes. A hung Docker build otherwise burns six hours.

  8. Names are lowercase. GHCR rejects uppercase repositories. IMAGE: ghcr.io/nuvraxis/<app> is written lowercase in env; the scaffold lowercases the app name.

pr.yaml

  1. on: pull_request with types: [opened, synchronize, reopened, ready_for_review] and no branches filter, so stacked PRs against feature branches are checked too. Every job has if: ${{ !github.event.pull_request.draft }}; marking ready triggers the run.

  2. Four parallel jobs: quality (biome ci --reporter=github, stylelint, turbo run typecheck test --affected, pnpm audit --audit-level high), build (turbo run build --affected), docker (build one platform with load: true, run it read-only with capabilities dropped, curl /api/health), helm (helm lint --strict and kubeconform on both values files). --affected needs fetch-depth: 0.

  3. Nothing is pushed from a PR. push: false, cache read-only (cache-from only), no registry login.

main.yaml

  1. on: push: branches: [main] builds the image once, for both architectures, and pushes it. Tags from docker/metadata-action: type=sha,format=short,prefix=sha- and type=raw,value=main, flavor: latest=false. latest belongs to releases.

  2. provenance: mode=max, sbom: true, cache-from/to: type=gha,scope=<app>,mode=max. Provenance and SBOM are attached to the image index; release.yaml carries them along when it retags. NEXT_DEPLOYMENT_ID=${{ github.sha }} is the build arg for skew protection.

  3. main.yaml doesn't publish the chart and doesn't re-run PR checks. Branch protection requires pr.yaml; main only produces the artefact.

release.yaml

  1. on: push: tags: ['v*.*.*'], then in order:

    1. Fail unless the tag is exactly vMAJOR.MINOR.PATCH and its commit is an ancestor of origin/main.
    2. Don't rebuild. If ghcr.io/nuvraxis/<app>:sha-<short> doesn't exist, fail with "let main.yaml finish, then re-run". No fallback build.
    3. docker buildx imagetools create --tag :vX.Y.Z --tag :latest <sha-image>: a manifest-level copy that keeps both architectures, provenance and SBOM, at the same digest.
    4. helm package --version X.Y.Z --app-version vX.Y.Z, helm push to oci://ghcr.io/nuvraxis/charts.
    5. gh release create vX.Y.Z --verify-tag --generate-notes with the chart .tgz, image-digest.txt and sbom.spdx.json attached.
  2. The release ritual: merge to main → wait for main.yaml to go green → git tag vX.Y.Z && git push origin vX.Y.Z. Tagging before main.yaml finishes fails step 2 on purpose; re-run the release job once the image exists. A bad release is fixed with a new patch tag, never by moving a tag.

Speeding things up (only when needed)

  • arm64 under QEMU is the slow part of main.yaml. Replace with a matrix on ubuntu-24.04-arm + ubuntu-latest pushing by digest, then a merge job with imagetools create. Keep the tags and the single index.
  • Turborepo remote cache for pr.yaml: see pnpm-turborepo.

Verify

docker run --rm -v "$PWD:/repo" -w /repo rhysd/actionlint:latest     # lint all workflows
gh workflow list && gh run list --limit 5
gh run view <run-id> --log-failed

After a release: docker buildx imagetools inspect ghcr.io/nuvraxis/<app>:vX.Y.Z shows both platforms, and helm show chart oci://ghcr.io/nuvraxis/charts/<app> --version X.Y.Z shows appVersion: vX.Y.Z.

Sources

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

Nuvraxis/nuvraxis-plugins

>- Biome 2.5 setup and rules for Nuvraxis monorepos — root biome.json with pinned $schema, VCS ignore, formatter settings, the recommended preset with a11y and the react/next domains, nursery policy, organize imports, overrides, nested per-package configs ("extends": "//"), biome check --write locally, biome ci in CI, VS Code settings, and migrating from ESLint/Prettier. Use when the repo has biome.json or biome.jsonc, @biomejs/biome in package.json, .eslintrc*/eslint.config.*/.prettierrc* to migrate, or when fixing lint and formatting errors.

Nuvraxis/nuvraxis-plugins

>- Dockerfile rules for Next.js standalone apps in a pnpm + Turborepo monorepo — multi-stage build (turbo prune → pnpm fetch/offline install → turbo build → minimal runner), pinned Node 26 Alpine by digest, checksum-verified pnpm binary, non-root uid 1001, read-only root filesystem with a writable .next/cache, HEALTHCHECK on /api/health, build args only for NEXT_PUBLIC_* values, BuildKit secrets and cache mounts, multi-arch, OCI labels and .dockerignore. Use when the repo has a Dockerfile, .dockerignore, compose file, or next.config with output "standalone", or when asked to containerise, shrink, harden or debug an image.

Nuvraxis/nuvraxis-plugins

>- Helm chart rules for Nuvraxis Next.js apps — one chart per app in charts/ (named after the app), published to oci://ghcr.io/nuvraxis/charts and synced by Argo CD; Chart.yaml version/appVersion set only by release.yaml; Deployment with startup/liveness/readiness probes on /api/health, non-root read-only security context, emptyDir for .next/cache, ConfigMap + existing Secret via envFrom, Service, Ingress with cert-manager, HPA, PDB, ServiceAccount, topology spread; no Helm hooks; helm lint --strict + kubeconform. Use when the repo has charts/, Chart.yaml, values*.yaml, templates/*.yaml with Helm syntax, or an Argo CD Application, or when asked to deploy, scale, expose or configure the app on Kubernetes.

Nuvraxis/nuvraxis-plugins

>- Production rules for Next.js 16 App Router apps at Nuvraxis — Server/Client Component boundaries, Cache Components ("use cache", cacheLife, cacheTag, updateTag), Server Actions, route handlers, env handling, instrumentation, output standalone and the /api/health route. Use when the project has "next" in package.json, an app/ or src/app/ directory, next.config.ts, proxy.ts, instrumentation.ts, or files named page.tsx, layout.tsx, route.ts, loading.tsx, error.tsx.

Related Skills