{"product_id":"github-actions-ci-cd-pipeline-template-pack","title":"GitHub Actions CI\/CD Pipeline Template Pack","description":"\u003ch3\u003eGitHub Actions CI\/CD Pipeline Template Pack\u003c\/h3\u003e\n\u003cp\u003eMost GitHub Actions workflows I encounter in enterprise environments are copy-pasted from blog posts and never updated. They use \u003ccode\u003eactions\/checkout@v2\u003c\/code\u003e when v4 has been out for a year, store AWS credentials as long-lived secrets, and have no security scanning whatsoever. When something breaks at 2 AM, the on-call engineer spends 30 minutes reading the YAML to understand what the pipeline is supposed to do because there are no comments, no documentation, and no error handling. This template is the opposite of that.\u003c\/p\u003e\n\n\u003cp\u003eBuilt from production pipelines I have maintained for defense and healthcare systems, this workflow follows GitHub's recommended patterns for action pinning, secret management, and job dependency structure.\u003c\/p\u003e\n\n\u003ch3\u003ePipeline Stages\u003c\/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cstrong\u003echeckout\u003c\/strong\u003e — \u003ccode\u003eactions\/checkout@v4\u003c\/code\u003e with \u003ccode\u003efetch-depth: 0\u003c\/code\u003e for full history access. Required for changelog generation, blame annotations, and accurate coverage diffs.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003esetup\u003c\/strong\u003e — Language-specific setup action (\u003ccode\u003eactions\/setup-node@v4\u003c\/code\u003e, \u003ccode\u003eactions\/setup-python@v5\u003c\/code\u003e, \u003ccode\u003eactions\/setup-go@v5\u003c\/code\u003e) pinned to exact versions. Dependency caching via \u003ccode\u003eactions\/cache@v4\u003c\/code\u003e with lockfile hash keys.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003elint\u003c\/strong\u003e — Language-appropriate linters run in parallel. Fast feedback loop — fails in under 60 seconds. Blocks the more expensive test and build stages.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003etest\u003c\/strong\u003e — Unit tests with coverage reporting. Matrix strategy for multiple runtime versions. JUnit XML output for GitHub's native test reporting. Coverage uploaded to Codecov.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003esecurity\u003c\/strong\u003e — \u003ccode\u003egithub\/codeql-action@v3\u003c\/code\u003e for SAST. \u003ccode\u003etrufflesecurity\/trufflehog@v3.63.0\u003c\/code\u003e for secret detection. \u003ccode\u003eactions\/dependency-review-action@v4\u003c\/code\u003e for vulnerable dependencies.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003ebuild\u003c\/strong\u003e — Application build with artifact upload. Docker image build if containerized. All artifacts tagged with \u003ccode\u003e${github.sha}\u003c\/code\u003e for traceability.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003edeploy\u003c\/strong\u003e — Environment-gated deployment with manual approval for production. Uses OIDC federation for cloud authentication — no stored credentials.\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch3\u003eSecurity Gates\u003c\/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cstrong\u003eAction pinning\u003c\/strong\u003e — All third-party actions pinned to SHA, not version tag. Prevents supply chain attacks where a tag is reassigned to a malicious commit.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eMinimum permissions\u003c\/strong\u003e — \u003ccode\u003epermissions:\u003c\/code\u003e block explicitly sets \u003ccode\u003econtents: read\u003c\/code\u003e, \u003ccode\u003epackages: write\u003c\/code\u003e as needed. No default \u003ccode\u003ewrite-all\u003c\/code\u003e.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eSecret scanning\u003c\/strong\u003e — TruffleHog runs on every PR. Blocks merge if any credential pattern is detected in the diff or commit history.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eOIDC authentication\u003c\/strong\u003e — Cloud provider authentication via federated identity. No AWS_ACCESS_KEY_ID, no AZURE_CLIENT_SECRET, no GCP JSON key files.\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch3\u003eEnvironment Promotion\u003c\/h3\u003e\n\u003cp\u003eDev auto-deploys on merge to develop. Staging deploys on release candidate tags with one required approval. Production deploys on release tags with two required approvals and passing staging tests.\u003c\/p\u003e\n\n\u003ch3\u003eWhat Breaks First\u003c\/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cstrong\u003eRunner disk space exhaustion\u003c\/strong\u003e — Large Docker builds on GitHub-hosted runners run out of the 14GB available disk. Fix: add \u003ccode\u003edocker system prune -af\u003c\/code\u003e before the build or use \u003ccode\u003eruns-on: ubuntu-latest-large\u003c\/code\u003e runners.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eConcurrent workflow cancellation\u003c\/strong\u003e — Multiple pushes to the same branch cancel each other via \u003ccode\u003econcurrency\u003c\/code\u003e groups. The latest push might cancel a deploy that was in progress. Fix: use \u003ccode\u003ecancel-in-progress: false\u003c\/code\u003e for deployment workflows.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eCache eviction under storage limit\u003c\/strong\u003e — GitHub caches are limited to 10GB per repository. Frequent cache writes push older caches out. Fix: use specific cache keys that minimize churn and delete stale caches via the REST API in a scheduled cleanup workflow.\u003c\/li\u003e\n\u003c\/ul\u003e","brand":"Citadel Cloud Management","offers":[{"title":"Default Title","offer_id":54890410934563,"sku":"CCM-DEV-001","price":39.0,"currency_code":"USD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0979\/8539\/7027\/files\/citadel-devops-product_8366228b-de79-4e61-beac-e6af2f3cc6b2.png?v=1775138086","url":"https:\/\/citadel-cloud-management.myshopify.com\/products\/github-actions-ci-cd-pipeline-template-pack","provider":"Citadel Cloud Management","version":"1.0","type":"link"}