CI/CD Pipeline
⚠️ Documentation Update in Progress: This document is being updated to reflect the migration from custom workflows to Release Please. The workflow numbers have changed:
- Workflows 2 (Version Update), 3 (Auto-Merge), and 4 (Create Tag) have been replaced by Release Please
- Workflow 5 (Publish Release) is now Workflow 2
- Workflow 6 (Cleanup) is now Workflow 3
📚 Note: For the most current workflow documentation, see GitHub Workflows Overview. This document provides detailed technical reference for the CI/CD pipeline.
Overview
Section titled “Overview”This document provides comprehensive technical documentation for the GitHub Actions CI/CD pipeline that powers the automated build, test, version management, and deployment workflows for the Warcraft II Notifications Plugin.
Pipeline Philosophy
Section titled “Pipeline Philosophy”The pipeline is designed around these core principles:
- Release Please Integration: Automated semantic versioning using Google’s Release Please
- Conventional Commits: Uses conventional commit patterns for semantic versioning
- Zero-Touch Deployment: Fully automated from PR merge to npm publication
- Quality Gates: Multi-stage validation with testing, type checking, and linting
- Independent Documentation: Documentation deploys immediately without version requirements
- Self-Healing: Automatic cleanup and error recovery
Quick Reference
Section titled “Quick Reference”| # | Workflow | Trigger | Duration | Purpose |
|---|---|---|---|---|
| 1 | Validate PR | Pull Request | ~2-3 min | Quality assurance (lint, test, build) |
| 2 | Publish Release | Tag push (v*) | ~3-4 min | Publish npm, docs, GitHub release |
| 3 | Cleanup | After publish | ~30 sec | Delete old branches and releases |
| - | Release Please | PR merge to main | ~1-2 min | Create release PR with changelog |
| - | Deploy Documentation | Push to main (docs) | ~30 sec | Independent docs deployment |
| - | Repo Config Check | Schedule, Manual | ~10 sec | Configuration validation |
Pipeline Architecture
Section titled “Pipeline Architecture”Complete Pipeline Flow
Section titled “Complete Pipeline Flow”Pipeline Stages
Section titled “Pipeline Stages”Stage 1: Quality Assurance (PR Validation)
Section titled “Stage 1: Quality Assurance (PR Validation)”Purpose: Ensure code quality before merge
Duration: 2-3 minutes
Parallel Jobs: 3 (validate, security, pr-analysis)
Stage 2: Semantic Versioning (Smart Version Bump)
Section titled “Stage 2: Semantic Versioning (Smart Version Bump)”Purpose: Determine and apply version bump
Duration: 1-2 minutes
AI-Powered: Yes (Google Gemini)
Stage 3: Release & Distribution (Release & Publish)
Section titled “Stage 3: Release & Distribution (Release & Publish)”Purpose: Build, test, and publish to npm
Duration: 3-4 minutes
Provenance: Enabled
Stage 4: Maintenance (Cleanup Workflows)
Section titled “Stage 4: Maintenance (Cleanup Workflows)”Purpose: Maintain repository hygiene
Frequency: Event-driven + Weekly
Workflow Details
Section titled “Workflow Details”PR Validation Workflow
Section titled “PR Validation Workflow”File: .github/workflows/pr-validation.yml
Purpose: Comprehensive quality assurance for all pull requests
Triggers
Section titled “Triggers”on: pull_request: branches: [main, develop] types: [opened, synchronize, reopened]Concurrency Control
Section titled “Concurrency Control”concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: trueBehavior: Cancels in-progress runs when new commits are pushed to the same PR.
Job 1: Validate
Section titled “Job 1: Validate”Purpose: Code quality validation
Runner: ubuntu-latest
Timeout: Default (360 minutes)
Steps Breakdown
Section titled “Steps Breakdown”-
Checkout Repository
- uses: actions/checkout@v4with:fetch-depth: 0 # Full history for accurate analysis -
Setup Bun Runtime
- uses: oven-sh/setup-bun@v2with:bun-version: 'latest'- Why Bun?: Faster package installation and test execution
- Version Strategy: Always use latest for development
-
Cache Dependencies
- uses: actions/cache@v4with:path: ~/.bun/install/cachekey: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }}restore-keys: |${{ runner.os }}-bun-- Cache Key: Based on OS and lockfile hash
- Fallback: Partial match on OS
- Performance Impact: ~30-60 second improvement
-
Install Dependencies
Terminal window bun install --frozen-lockfile- Frozen Lockfile: Ensures reproducible builds
- Fails if: lockfile is out of sync with package.json
-
Format Check
Terminal window bun run format:check- Tool: Prettier
- Config:
.prettierrc - Scope: All TypeScript, JavaScript, JSON, Markdown files
-
Linting
Terminal window bun run lint- Tool: ESLint
- Config:
eslint.config.cjs - Rules: TypeScript, Import, JSDoc, SonarJS, Prettier integration
-
Type Checking
Terminal window bun run type-check- Tool: TypeScript Compiler
- Config:
tsconfig.test.json - Mode: No emit, type checking only
-
Test with Coverage
Terminal window bun run test:coverage- Framework: Bun’s built-in test runner
- Coverage: Enabled
- Scope:
src/directory
-
Build Project
Terminal window bun run build- Tool: TypeScript Compiler
- Output: Compiled JavaScript
- Validation: Ensures production build succeeds
-
Upload Coverage
- uses: codecov/codecov-action@v4if: always()with:token: ${{ secrets.CODECOV_TOKEN }}fail_ci_if_error: false- Service: Codecov
- Behavior: Always runs, even if tests fail
- Failure Mode: Non-blocking
Job 2: Security
Section titled “Job 2: Security”Purpose: Vulnerability scanning
Runner: ubuntu-latest
Steps Breakdown
Section titled “Steps Breakdown”-
Trivy Vulnerability Scanner
- uses: aquasecurity/trivy-action@masterwith:scan-type: 'fs'scan-ref: '.'format: 'sarif'output: 'trivy-results.sarif'- Scan Type: Filesystem
- Target: Entire repository
- Output Format: SARIF (Static Analysis Results Interchange Format)
-
Upload SARIF Results
- uses: github/codeql-action/upload-sarif@v3if: always()with:sarif_file: 'trivy-results.sarif'- Integration: GitHub Security tab
- Visibility: Security alerts visible in PR and repository
Job 3: PR Analysis
Section titled “Job 3: PR Analysis”Purpose: Analyze PR size and complexity
Runner: ubuntu-latest
Steps Breakdown
Section titled “Steps Breakdown”-
Analyze PR Size
Terminal window CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD | wc -l)ADDED_LINES=$(git diff --numstat origin/${{ github.base_ref }}...HEAD | awk '{added+=$1} END {print added+0}')DELETED_LINES=$(git diff --numstat origin/${{ github.base_ref }}...HEAD | awk '{deleted+=$2} END {print deleted+0}') -
Large PR Detection
- Threshold: 20+ files OR 500+ added lines
- Action: Post warning comment
-
Comment on Large PRs
github.rest.issues.createComment({issue_number: context.issue.number,owner: context.repo.owner,repo: context.repo.repo,body: `⚠️ **Large PR Warning**...`,});
Quality Gates
Section titled “Quality Gates”All jobs must pass for PR to be mergeable:
- ✅ Code formatting compliant
- ✅ No linting errors
- ✅ Type checking passes
- ✅ All tests pass with coverage
- ✅ Build succeeds
- ✅ No critical security vulnerabilities
Smart Version Bump Workflow
Section titled “Smart Version Bump Workflow”File: .github/workflows/smart-version-bump.yml
Purpose: AI-powered semantic versioning with cross-validation
Triggers
Section titled “Triggers”on: push: branches: [main] paths-ignore: - '.github/**' - 'docs/**' - '*.md' workflow_dispatch: inputs: version_type: description: 'Force version bump type' required: false type: choice options: ['auto', 'major', 'minor', 'patch'] default: 'auto'Concurrency Control
Section titled “Concurrency Control”concurrency: group: version-bump-${{ github.ref }} cancel-in-progress: false # Never cancel version bumpsCritical: Version bumps must complete to prevent state inconsistencies.
Job 1: Analyze Changes
Section titled “Job 1: Analyze Changes”Purpose: Determine appropriate version bump
Runner: ubuntu-latest
Cycle Prevention
Section titled “Cycle Prevention”LATEST_COMMIT_MSG=$(git log -1 --pretty=format:"%s")if [[ "$LATEST_COMMIT_MSG" =~ ^chore:\ (bump\ version|sync\ package\.json\ version) ]] || [[ "$LATEST_COMMIT_MSG" =~ \[skip\ ci\] ]]; then echo "🛑 Skipping version bump to prevent cycle" exit 0fiPrevents: Infinite loop of version bump commits triggering more version bumps.
Commit Analysis
Section titled “Commit Analysis”-
Get Commits Since Last Tag
Terminal window LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")if [ -z "$LATEST_TAG" ]; thenCOMMITS=$(git log --oneline --no-merges)elseCOMMITS=$(git log ${LATEST_TAG}..HEAD --oneline --no-merges)fi -
Squash Merge Detection
Terminal window COMMIT_COUNT=$(echo "$COMMITS" | wc -l)if [ "$COMMIT_COUNT" -eq 1 ]; thenecho "✅ Single commit detected (likely squash merge)"fi
AI Analysis with Google Gemini
Section titled “AI Analysis with Google Gemini”-
Install Gemini CLI
Terminal window curl -o- https://generativelanguage.googleapis.com/install.sh | bash -
Create Analysis Prompt
You are a semantic versioning expert. Analyze the following git commits and file changes to determine the appropriate version bump.Rules:- MAJOR: Breaking changes, API changes, major architecture changes- MINOR: New features, new functionality, backwards-compatible additions- PATCH: Bug fixes, documentation updates, small improvements, refactoring- NONE: Only CI/config changes, formatting, or no significant changes -
Execute AI Analysis
Terminal window AI_DECISION=$(gemini generate "$(cat analysis_prompt.txt)" 2>/dev/null | tail -1 | tr -d '\n\r' | tr '[:lower:]' '[:upper:]')
Fallback: Conventional Commits Analysis
Section titled “Fallback: Conventional Commits Analysis”If AI fails or returns invalid response:
if grep -qi "BREAKING CHANGE\|!:" commits.txt; then AI_DECISION="MAJOR"elif grep -qi "^feat\|^feature" commits.txt; then AI_DECISION="MINOR"elif grep -qi "^fix\|^bugfix\|^patch" commits.txt; then AI_DECISION="PATCH"else AI_DECISION="PATCH"fiCross-Validation
Section titled “Cross-Validation”# Independent conventional commit analysisif grep -qi "BREAKING CHANGE\|!:" commits.txt; then CONVENTIONAL_DECISION="MAJOR"elif grep -qi "^feat\|^feature" commits.txt; then CONVENTIONAL_DECISION="MINOR"# ... etcfi
# Compare decisionsif [ "$AI_DECISION" != "$CONVENTIONAL_DECISION" ]; then echo "⚠️ WARNING: Version analysis mismatch detected!" # Use higher semantic version level as safer default if [[ "$CONVENTIONAL_DECISION" == "MAJOR" ]] || [[ "$AI_DECISION" == "MAJOR" ]]; then FINAL_DECISION="MAJOR" elif [[ "$CONVENTIONAL_DECISION" == "MINOR" ]] || [[ "$AI_DECISION" == "MINOR" ]]; then FINAL_DECISION="MINOR" else FINAL_DECISION="PATCH" fifiSafety Mechanism: Always chooses the higher semantic version level when there’s disagreement.
Version Calculation
Section titled “Version Calculation”# Calculate new version based on latest tagIFS='.' read -r -a version_parts <<< "$CURRENT_VERSION"major=${version_parts[0]}minor=${version_parts[1]}patch=${version_parts[2]}
case $VERSION_TYPE in major) major=$((major + 1)) minor=0 patch=0 ;; minor) minor=$((minor + 1)) patch=0 ;; patch) patch=$((patch + 1)) ;;esac
NEW_VERSION="${major}.${minor}.${patch}"Job 2: Update Version & Create Tag
Section titled “Job 2: Update Version & Create Tag”Purpose: Apply version bump and create release tag
Runner: ubuntu-latest
Depends On: analyze-changes
Tag Existence Check
Section titled “Tag Existence Check”if git tag -l "v$NEW_VERSION" | grep -q "v$NEW_VERSION"; then echo "⚠️ Tag v$NEW_VERSION already exists locally - skipping" exit 0elif git ls-remote --tags origin | grep -q "refs/tags/v$NEW_VERSION$"; then echo "⚠️ Tag v$NEW_VERSION already exists on remote - skipping" exit 0fiPrevents: Duplicate tags from workflow re-runs.
Update package.json
Section titled “Update package.json”const fs = require('fs');const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));pkg.version = '$NEW_VERSION';fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');Commit and Tag
Section titled “Commit and Tag”git add package.jsongit commit -m "chore: bump version to $NEW_VERSION
Version Type: ${{ needs.analyze-changes.outputs.version_type }}AI Analysis: ${{ needs.analyze-changes.outputs.ai_decision }}
This commit will be tagged as v$NEW_VERSION"
git tag -a "v$NEW_VERSION" -m "Release v$NEW_VERSION
Version Type: ${{ needs.analyze-changes.outputs.version_type }}AI Analysis: ${{ needs.analyze-changes.outputs.ai_decision }}
This tag will trigger NPM publishing via release-publish.yml"
git push origin main && git push origin --tagsOutputs
Section titled “Outputs”outputs: should_bump: ${{ steps.decision.outputs.should_bump }} version_type: ${{ steps.decision.outputs.version_type }} new_version: ${{ steps.decision.outputs.new_version }} ai_decision: ${{ steps.ai-analysis.outputs.ai_decision }} conventional_decision: ${{ steps.validation.outputs.conventional_decision }} mismatch_detected: ${{ steps.validation.outputs.mismatch_detected }}Sync Package Version Workflow
Section titled “Sync Package Version Workflow”File: .github/workflows/sync-package-version.yml
Purpose: Legacy workflow for version synchronization (mostly obsolete with Smart Version Bump)
Triggers
Section titled “Triggers”on: push: tags: - 'v*' workflow_dispatch: inputs: tag: description: 'Tag to sync (e.g., v1.2.3)' required: true type: stringJob 1: Check Sync Needed
Section titled “Job 1: Check Sync Needed”Purpose: Determine if package.json needs updating
Runner: ubuntu-latest
VERSION=${TAG#v}PACKAGE_VERSION=$(node -p "require('./package.json').version")
if [ "$PACKAGE_VERSION" = "$VERSION" ]; then echo "✅ Package.json version already matches tag - no sync needed" echo "sync_needed=false" >> $GITHUB_OUTPUTelse echo "📦 Package.json needs sync (legacy mode)" echo "sync_needed=true" >> $GITHUB_OUTPUTfiJob 2: Sync Package Version
Section titled “Job 2: Sync Package Version”Purpose: Create PR to sync package.json (legacy mode)
Runner: ubuntu-latest
Condition: Only runs if sync needed
Note: With Smart Version Bump, this workflow typically skips execution as package.json is already updated before tag creation.
Release & Publish Workflow
Section titled “Release & Publish Workflow”File: .github/workflows/release-publish.yml
Purpose: Build, test, and publish package to npm with provenance
Triggers
Section titled “Triggers”on: push: tags: - 'v*' workflow_dispatch: inputs: tag: description: 'Tag to publish (e.g., v1.2.3)' required: true type: stringPermissions
Section titled “Permissions”permissions: contents: write # Create releases id-token: write # npm provenanceProvenance: Enables npm package provenance for supply chain security.
Job: Publish
Section titled “Job: Publish”Purpose: Complete release pipeline
Runner: ubuntu-latest
Version Verification
Section titled “Version Verification”PACKAGE_VERSION=$(node -p "require('./package.json').version")TAG_VERSION="${{ steps.version.outputs.version }}"
if [ "$PACKAGE_VERSION" != "$TAG_VERSION" ]; then echo "❌ Version mismatch: package.json ($PACKAGE_VERSION) != tag ($TAG_VERSION)" exit 1fiCritical: Ensures package.json and tag are in sync before publishing.
Full Test Suite
Section titled “Full Test Suite”echo "🧪 Running linter..."bun run lint
echo "🔍 Type checking..."bun run type-check
echo "🧪 Running tests with coverage..."bun run test:coverage
echo "🏗️ Building project..."bun run buildQuality Gate: All must pass before publishing.
Publication Check
Section titled “Publication Check”PACKAGE_NAME=$(node -p "require('./package.json').name")VERSION="${{ steps.version.outputs.version }}"
if npm view "$PACKAGE_NAME@$VERSION" version 2>/dev/null; then echo "already_published=true" >> $GITHUB_OUTPUT echo "⚠️ Version $VERSION is already published to npm"else echo "already_published=false" >> $GITHUB_OUTPUT echo "✅ Version $VERSION is not yet published"fiIdempotency: Prevents duplicate publications.
npm Publish
Section titled “npm Publish”npm publish --access public --provenanceFlags:
--access public: Package is publicly accessible--provenance: Generates provenance attestation linking package to source
GitHub Release Creation
Section titled “GitHub Release Creation”// Get or create releaselet release;try { const { data } = await github.rest.repos.getReleaseByTag({ owner: context.repo.owner, repo: context.repo.repo, tag: tag, }); release = data;} catch (error) { if (error.status === 404) { const { data } = await github.rest.repos.createRelease({ owner: context.repo.owner, repo: context.repo.repo, tag_name: tag, name: `Release ${tag}`, body: `Release ${version}`, draft: false, prerelease: false, }); release = data; }}
// Update with npm infoconst npmUrl = `https://www.npmjs.com/package/${npmPackageName}/v/${version}`;const updatedBody = `${release.body}
## 📦 Package Information
- **npm Package:** [\`${npmPackageName}@${version}\`](${npmUrl})- **Status:** ${publishedStatus}- **Installation:** \`npm install ${npmPackageName}@${version}\`
## Build Information
- **Node.js:** 20.x- **Runtime:** Bun- **Build Status:** ✅ Passed- **Tests:** ✅ Passed with coverage`;Post-Publish Validation
Section titled “Post-Publish Validation”# Wait for npm to propagate with retry logicfor i in {1..6}; do echo "Attempt $i/6: Checking if package is available..." if npm view "$PACKAGE_NAME@$VERSION" version >/dev/null 2>&1; then echo "✅ Successfully validated npm package: $PACKAGE_NAME@$VERSION" exit 0 else if [ $i -lt 6 ]; then echo "Package not yet available, waiting 15 seconds..." sleep 15 fi fidoneRetry Logic: 6 attempts with 15-second delays (90 seconds total).
Auto-Merge Bot Workflow
Section titled “Auto-Merge Bot Workflow”File: .github/workflows/auto-merge-bot.yml
Purpose: Automatically merge version sync PRs after validation
Triggers
Section titled “Triggers”on: pull_request: types: [opened, synchronize, reopened] check_suite: types: [completed] workflow_run: workflows: ['PR Validation'] types: [completed]Script: .github/scripts/auto-merge.cjs
Section titled “Script: .github/scripts/auto-merge.cjs”PR Identification
Section titled “PR Identification”// Extract PR number based on event typelet prNumber = null;
if (GITHUB_EVENT_NAME === 'pull_request') { prNumber = eventPayload.pull_request?.number;} else if ( GITHUB_EVENT_NAME === 'workflow_run' && eventPayload.workflow_run?.pull_requests?.length > 0) { prNumber = eventPayload.workflow_run.pull_requests[0].number;} else if ( GITHUB_EVENT_NAME === 'check_suite' && eventPayload.check_suite?.pull_requests?.length > 0) { prNumber = eventPayload.check_suite.pull_requests[0].number;}Version Sync PR Detection
Section titled “Version Sync PR Detection”const isVersionSyncPR = /^chore: sync package\.json version to \d+\.\d+\.\d+$/.test(prData.title) && prData.headRefName.startsWith('sync-version/') && prData.author.login === 'github-actions[bot]' && prData.state === 'OPEN';Check Status Validation
Section titled “Check Status Validation”const checksJson = exec(`gh pr checks ${prNumber} --json state,conclusion`);const checks = JSON.parse(checksJson);
const hasFailedChecks = checks.some( (check) => check.state === 'COMPLETED' && check.conclusion !== 'SUCCESS',);
const hasPendingChecks = checks.some( (check) => check.state === 'IN_PROGRESS' || check.state === 'QUEUED',);Auto-Merge Execution
Section titled “Auto-Merge Execution”gh pr merge ${prNumber} --squash --auto --delete-branchFlags:
--squash: Enforce single commit per merge--auto: Enable auto-merge when checks pass--delete-branch: Clean up after merge
Cleanup Merged Branches Workflow
Section titled “Cleanup Merged Branches Workflow”File: .github/workflows/cleanup-merged-branches.yml
Purpose: Automatic branch cleanup after PR merge
Triggers
Section titled “Triggers”on: pull_request: types: [closed] schedule: - cron: '0 2 * * 0' # Weekly on Sundays at 2 AM UTC workflow_dispatch:Job: Cleanup Merged Branches
Section titled “Job: Cleanup Merged Branches”PR Trigger (Immediate Cleanup)
Section titled “PR Trigger (Immediate Cleanup)”BRANCH_NAME="${{ github.event.pull_request.head.ref }}"REPO_OWNER="${{ github.event.pull_request.head.repo.owner.login }}"CURRENT_REPO_OWNER="${{ github.repository_owner }}"
# Only delete if it's from the same repository (not a fork)if [ "$REPO_OWNER" = "$CURRENT_REPO_OWNER" ]; then echo "Deleting merged branch: $BRANCH_NAME" git push origin --delete "$BRANCH_NAME"fiScheduled Cleanup (Batch Processing)
Section titled “Scheduled Cleanup (Batch Processing)”# Get all remote branches that have been merged into mainMERGED_BRANCHES=$(git branch -r --merged origin/main | grep -v 'origin/main' | grep -v 'origin/HEAD' | sed 's/origin\///' | xargs)
for branch in $MERGED_BRANCHES; do # Skip protected branches if [[ "$branch" =~ ^(main|master|develop|staging|production)$ ]]; then continue fi
# Skip branches less than 1 day old BRANCH_AGE=$(git log -1 --format="%ct" "origin/$branch" 2>/dev/null || echo "0") CURRENT_TIME=$(date +%s) AGE_DAYS=$(( (CURRENT_TIME - BRANCH_AGE) / 86400 ))
if [ $AGE_DAYS -lt 1 ]; then continue fi
git push origin --delete "$branch"doneSafety Features:
- Skips protected branches (main, master, develop, staging, production)
- Only deletes branches older than 1 day
- Only deletes branches merged into main
Cleanup Old Releases Workflow
Section titled “Cleanup Old Releases Workflow”File: .github/workflows/cleanup-old-releases.yml
Purpose: Maintain manageable release history
Triggers
Section titled “Triggers”on: workflow_dispatch: inputs: dry_run: description: 'Dry run - only show what would be deleted' required: false default: true type: boolean schedule: - cron: '0 2 * * 0' # Weekly on Sundays at 2 AM UTC push: tags: - 'v*'Retention Policy
Section titled “Retention Policy”// Keep up to 5 major versionsconst majorsToKeep = majorVersions.slice(0, 5);
// For current major: keep up to 10 minor/patch releasesif (isCurrentMajor) { const keepCount = Math.min(10, releases.length); const releasesToKeep = releases.slice(0, keepCount); const releasesToDelete = releases.slice(keepCount);}
// For older majors: keep only the latest releaseelse { const latestRelease = releases[0]; const olderReleases = releases.slice(1);}Policy Summary:
- Keep last 5 major versions
- For current major: keep last 10 releases
- For older majors: keep only latest release per major
Release Deletion
Section titled “Release Deletion”for (const item of uniqueToDelete) { // Delete release await github.rest.repos.deleteRelease({ owner: context.repo.owner, repo: context.repo.repo, release_id: item.release.id, });
// Delete git tag await github.rest.git.deleteRef({ owner: context.repo.owner, repo: context.repo.repo, ref: `tags/${item.tag.replace(/^v/, 'v')}`, });
// Rate limiting protection await new Promise((resolve) => setTimeout(resolve, 500));}Safety Features:
- Dry run mode by default
- Semantic version parsing
- Rate limiting protection (500ms delay between deletions)
Deploy Documentation Workflow
Section titled “Deploy Documentation Workflow”File: .github/workflows/deploy-docs.yml
Purpose: Build and deploy documentation to GitHub Pages using Astro’s official action
Overview
Section titled “Overview”The documentation deployment workflow uses GitHub Actions with the official Astro action:
mainbranch: Contains source markdown files and build configuration- Artifact-based deployment: No separate branch needed - uses GitHub Pages artifacts
- Astro action: Uses
withastro/action@v3for optimized builds and deployment
This approach ensures clean version control history, faster builds, and automated documentation deployment.
Triggers
Section titled “Triggers”on: push: branches: [main] paths: - 'docs/**' - 'pages/**' release: types: [published] workflow_dispatch:Trigger Conditions:
- Pushes to
mainbranch that modifydocs/**orpages/**directories - New releases are published
- Manual workflow dispatch
Permissions
Section titled “Permissions”permissions: contents: read pages: write id-token: writeCritical: The workflow needs pages: write and id-token: write permissions for GitHub Pages deployment.
Concurrency Control
Section titled “Concurrency Control”concurrency: group: 'pages' cancel-in-progress: falseBehavior: Only one documentation deployment runs at a time. New deployments wait for current deployment to complete (no cancellation).
Job 1: Build Documentation
Section titled “Job 1: Build Documentation”Purpose: Build static site and upload as artifact
Runner: ubuntu-latest
Duration: 2-5 minutes
Workflow Steps
Section titled “Workflow Steps”-
Checkout Repository
- name: Checkout repositoryuses: actions/checkout@v4with:fetch-depth: 0 # Full history for accurate build -
Setup Bun Runtime
- name: Setup Bunuses: oven-sh/setup-bun@v2with:bun-version: latest- Why Bun?: 10-20x faster package installation than npm
- Version Strategy: Always use latest for documentation builds
-
Install Dependencies
Terminal window cd pagesbun install --frozen-lockfile- Installs Astro, Starlight, and all documentation dependencies
- Uses
bun.lockfor reproducible builds
-
Install Playwright Browsers
Terminal window cd pagesbunx playwright install --with-deps chromium- Required for link verification and testing
-
Transform Documentation
Terminal window cd pagesnode transform-docs.js- Syncs markdown files from
./docs/to./pages/src/content/docs/
- Syncs markdown files from
-
Build and Upload with Astro Action
- name: Build and upload with Astro actionuses: withastro/action@v3with:path: ./pagespackage-manager: bun@latestAction Benefits:
- Optimized Astro builds with caching
- Automatic artifact upload to GitHub Pages
- Built-in error handling
- Official Astro support
-
Verify Internal Links
Terminal window cd pagesbun run verify- Validates all internal links in the built site
- Prevents broken links from being deployed
Job 2: Deploy to GitHub Pages
Section titled “Job 2: Deploy to GitHub Pages”Purpose: Deploy built artifacts to GitHub Pages
Runner: ubuntu-latest
Duration: 30 seconds
Workflow Steps
Section titled “Workflow Steps”-
Deploy to GitHub Pages
- name: Deploy to GitHub Pagesid: deploymentuses: actions/deploy-pages@v4- Deploys the artifact uploaded by the build job
- Creates/updates the
github-pagesenvironment - Returns the deployment URL
-
Generate Summary
- Creates a deployment summary with URL, commit SHA, and build details
- Visible in the GitHub Actions workflow run
Build Process Details
Section titled “Build Process Details”Generated Artifacts
Section titled “Generated Artifacts”The GitHub Pages artifact contains:
pages artifact/├── _astro/ # JavaScript/CSS bundles│ ├── *.js│ └── *.css├── pagefind/ # Search index│ ├── fragment/│ ├── index/│ └── *.js├── collections/ # Content collections│ └── docs.schema.json├── *.html # Generated pages├── favicon.svg # Favicon├── content-assets.mjs # Asset mappings└── content-modules.mjs # Module mappingsNote: No separate branch is created - artifacts are stored in GitHub Pages service.
GitHub Pages Configuration
Section titled “GitHub Pages Configuration”After first workflow run, configure GitHub Pages:
- Go to: Settings → Pages
- Set Source: GitHub Actions
- Click Save (if required)
URL: https://pantheon-org.github.io/opencode-warcraft-notifications/
Monitoring
Section titled “Monitoring”Workflow Status:
# List recent documentation deploymentsgh run list --workflow=deploy-docs.yml --limit 5
# View specific rungh run view <run-id> --log
# Watch current rungh run watchDeployment Verification:
# Verify site is accessiblecurl -I https://pantheon-org.github.io/opencode-warcraft-notifications/
# Check deployment statusgh api repos/:owner/:repo/pages/deployments --jq '.[0]'
# View environment deploymentsgh api repos/:owner/:repo/environments/github-pages/deployments --jq '.[]| {created_at, environment, state}'Troubleshooting
Section titled “Troubleshooting”Issue 1: Deployment not triggered
Symptoms: Workflow completes but no deployment occurs
Solution:
- Check workflow logs for errors
- Verify
pages: writeandid-token: writepermissions in workflow - Check repository Actions permissions (Settings → Actions → General)
- Verify GitHub Pages source is set to “GitHub Actions” (Settings → Pages)
- Manually trigger workflow: Actions → Deploy Documentation → Run workflow
Issue 2: GitHub Pages not updating
Symptoms: Site shows old content after deployment
Solution:
- Verify GitHub Pages source is set to “GitHub Actions” (not a branch)
- Check deployment status: Repository → Environments → github-pages
- Hard refresh browser: Ctrl+Shift+R (Windows/Linux) or Cmd+Shift+R (Mac)
- Wait 1-2 minutes for GitHub Pages propagation
- Check workflow summary for deployment URL
Issue 3: Build failures
Symptoms: Workflow fails during build step
Solution:
- Check workflow logs for specific error
- Verify all markdown files have valid frontmatter
- Check for broken internal links (link verification step)
- Test build locally:
cd pages && bun install && bun run build - Verify dependencies are up to date in
pages/bun.lock
Issue 4: Link verification failures
Symptoms: Workflow fails at “Verify internal links” step
Solution:
- Run link verification locally:
cd pages && bun run verify - Fix any broken internal links in source markdown files
- Ensure all referenced files exist in
./docs/ - Re-run the workflow after fixing links
Issue 5: Permission denied errors
Symptoms: “Permission denied” or “Resource not accessible”
Solution:
- Verify workflow has
pages: writeandid-token: writepermissions - Check repository Actions permissions:
- Settings → Actions → General
- Workflow permissions → “Read and write permissions”
- Verify
GITHUB_TOKENis available in workflow
Performance Metrics
Section titled “Performance Metrics”- Cold build: 2-5 minutes (first run or cache miss)
- Warm build: 1-3 minutes (with dependency cache)
- Deployment propagation: 1-2 minutes (GitHub Pages)
- Total time to live: 3-7 minutes (commit to visible)
Related Documentation
Section titled “Related Documentation”- Deployment Guide - User-facing deployment docs
- Development Guide - Local documentation development
- GitHub Workflows Overview - Complete workflow documentation
Repository Configuration Check Workflow
Section titled “Repository Configuration Check Workflow”File: .github/workflows/repo-config-check.yml
Purpose: Validate repository settings for single-release-per-PR
Triggers
Section titled “Triggers”on: workflow_dispatch: schedule: - cron: '0 9 * * 1' # Weekly on Mondays at 9 AM UTC push: paths: - '.github/scripts/check-repo-config.cjs' - '.github/workflows/repo-config-check.yml'Script: .github/scripts/check-repo-config.cjs
Section titled “Script: .github/scripts/check-repo-config.cjs”Repository Settings Check
Section titled “Repository Settings Check”const repoData = exec( 'gh api repos/pantheon-org/opencode-warcraft-notifications --jq "{allow_squash_merge, allow_merge_commit, allow_rebase_merge, delete_branch_on_merge}"',);
const settings = JSON.parse(repoData);
const isOptimal = settings.allow_squash_merge === true && settings.allow_merge_commit === false && settings.allow_rebase_merge === false && settings.delete_branch_on_merge === true;Required Configuration:
- ✅ Allow squash merging:
true - ❌ Allow merge commits:
false - ❌ Allow rebase merging:
false - ✅ Delete branch on merge:
true
Issue Creation on Failure
Section titled “Issue Creation on Failure”if (!isOptimal) { await github.rest.issues.create({ owner: context.repo.owner, repo: context.repo.repo, title: '🔧 Repository Configuration Issue: Single Release per Merge Request', labels: ['configuration', 'automation', 'bug'], body: `## Issue
The repository configuration check detected that the current settings may allow multiple releases per merge request.
## Solution
Please review and apply the configuration changes detailed in: - 📚 **Documentation**: [docs/squash-merge-configuration.md](./docs/squash-merge-configuration.md) ...`, });}Environment Configuration
Section titled “Environment Configuration”Runtime Requirements
Section titled “Runtime Requirements”Bun Runtime
Section titled “Bun Runtime”Version: Latest
Purpose: Fast package management and test execution
- uses: oven-sh/setup-bun@v2 with: bun-version: 'latest'Why Bun?
- 10-20x faster package installation than npm
- Built-in test runner with coverage
- Native TypeScript support
- Compatible with Node.js ecosystem
Node.js Runtime
Section titled “Node.js Runtime”Version: 20.x
Purpose: npm publishing compatibility
- uses: actions/setup-node@v4 with: node-version: '20' registry-url: 'https://registry.npmjs.org' always-auth: trueWhy Node 20?
- LTS version with long-term support
- Required for npm provenance
- Stable npm CLI
Dependency Caching
Section titled “Dependency Caching”Bun Cache
Section titled “Bun Cache”- uses: actions/cache@v4 with: path: ~/.bun/install/cache key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }} restore-keys: | ${{ runner.os }}-bun-Cache Strategy:
- Primary Key: OS + lockfile hash (exact match)
- Fallback Key: OS only (partial match)
- Invalidation: Automatic on lockfile change
Performance Impact:
- Cold cache: ~60-90 seconds
- Warm cache: ~10-20 seconds
- Savings: ~40-70 seconds per workflow run
Secrets Management
Section titled “Secrets Management”Required Secrets
Section titled “Required Secrets”NPM_TOKEN
Section titled “NPM_TOKEN”Purpose: Authenticate npm publishing
Type: npm Access Token
Scope: Automation (publish-only)
Setup:
- Go to npmjs.com → Account Settings → Access Tokens
- Generate new token with “Automation” type
- Add to GitHub: Settings → Secrets → Actions → New repository secret
- Name:
NPM_TOKEN
Security:
- ✅ Automation tokens cannot be used for login
- ✅ Can be revoked without affecting other tokens
- ✅ Scoped to specific packages
WORKFLOW_PAT (Optional but Recommended)
Section titled “WORKFLOW_PAT (Optional but Recommended)”Purpose: Enable workflow-to-workflow triggering
Type: Personal Access Token (Classic)
Scope: repo, workflow
Why Needed?
- Default
GITHUB_TOKENcannot trigger other workflows (security feature) - Smart Version Bump needs to trigger Release & Publish
- Without PAT: Manual intervention required
Setup:
- Go to GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic)
- Generate new token with scopes:
repo,workflow - Add to repository: Settings → Secrets → Actions → New repository secret
- Name:
WORKFLOW_PAT
Security Considerations:
- ⚠️ PAT has broader permissions than
GITHUB_TOKEN - ✅ Use fine-grained tokens when available
- ✅ Set expiration date
- ✅ Regularly rotate tokens
CODECOV_TOKEN
Section titled “CODECOV_TOKEN”Purpose: Upload coverage reports to Codecov
Type: Codecov Upload Token
Required: No (workflow continues without it)
Setup:
- Go to codecov.io → Repository Settings
- Copy upload token
- Add to GitHub secrets as
CODECOV_TOKEN
GOOGLE_AI_API_KEY
Section titled “GOOGLE_AI_API_KEY”Purpose: Enable AI-powered version analysis
Type: Google AI (Gemini) API Key
Required: No (falls back to conventional commits)
Setup:
- Go to Google AI Studio
- Generate API key
- Add to GitHub secrets as
GOOGLE_AI_API_KEY
Fallback Behavior:
- If missing or invalid: Uses conventional commit analysis only
- No workflow failure
Secret Usage Patterns
Section titled “Secret Usage Patterns”Conditional Secret Usage
Section titled “Conditional Secret Usage”- name: Upload coverage reports uses: codecov/codecov-action@v4 if: always() with: token: ${{ secrets.CODECOV_TOKEN }} fail_ci_if_error: false # Don't fail if token missingSecret Validation
Section titled “Secret Validation”if [ -z "${{ secrets.NPM_TOKEN }}" ]; then echo "❌ NPM_TOKEN secret is required for publishing" exit 1fiMonitoring & Observability
Section titled “Monitoring & Observability”Workflow Status Monitoring
Section titled “Workflow Status Monitoring”GitHub Actions Dashboard
Section titled “GitHub Actions Dashboard”Location: Repository → Actions tab
Key Metrics:
- Workflow run status (success/failure/cancelled)
- Run duration
- Job-level status
- Step-level logs
Status Badges
Section titled “Status Badges”Add to README.md:
Coverage Monitoring
Section titled “Coverage Monitoring”Codecov Integration
Section titled “Codecov Integration”Dashboard: codecov.io/gh/pantheon-org/opencode-warcraft-notifications
Metrics:
- Overall coverage percentage
- Coverage trends over time
- File-level coverage
- PR coverage diff
Badge:
[](https://codecov.io/gh/pantheon-org/opencode-warcraft-notifications)Security Monitoring
Section titled “Security Monitoring”GitHub Security Tab
Section titled “GitHub Security Tab”Location: Repository → Security → Code scanning alerts
Sources:
- Trivy vulnerability scanner (PR Validation)
- Dependabot alerts
- Secret scanning
Alert Types:
- High/Medium/Low severity vulnerabilities
- Dependency vulnerabilities
- Code quality issues
npm Package Monitoring
Section titled “npm Package Monitoring”npm Package Page
Section titled “npm Package Page”URL: https://www.npmjs.com/package/@pantheon-ai/opencode-warcraft-notifications
Metrics:
- Download statistics
- Version history
- Provenance information
- Package size
Provenance Verification
Section titled “Provenance Verification”npm view @pantheon-ai/opencode-warcraft-notifications@latest --json | jq .dist.attestationsVerifies:
- Package built by GitHub Actions
- Source repository linkage
- Build environment integrity
Release Monitoring
Section titled “Release Monitoring”GitHub Releases
Section titled “GitHub Releases”Location: Repository → Releases
Information:
- Release notes
- npm package links
- Build information
- Download statistics
Notification Channels
Section titled “Notification Channels”GitHub Notifications
Section titled “GitHub Notifications”Automatic Notifications For:
- Workflow failures
- Security alerts
- PR comments (large PR warnings)
- Auto-merge status
Configuration: Settings → Notifications
Email Notifications
Section titled “Email Notifications”Setup: GitHub account settings → Notifications → Email preferences
Recommended:
- ✅ Workflow failures
- ✅ Security alerts
- ❌ Workflow successes (too noisy)
Troubleshooting
Section titled “Troubleshooting”Common Issues
Section titled “Common Issues”Issue 1: Version Bump Not Triggering
Section titled “Issue 1: Version Bump Not Triggering”Symptoms:
- PR merged to main
- No version bump workflow run
- No new tag created
Possible Causes:
-
Workflow-Generated Commit
Terminal window # Check latest commit messagegit log -1 --pretty=format:"%s"- If contains “chore: bump version” or “[skip ci]”: Cycle prevention activated
- Solution: This is expected behavior, no action needed
-
Path Filters Excluding Changes
paths-ignore:- '.github/**'- 'docs/**'- '*.md'- If only these paths changed: Workflow skipped
- Solution: Make substantive code changes
-
Missing WORKFLOW_PAT
- Smart Version Bump runs but doesn’t trigger Release & Publish
- Solution: Add
WORKFLOW_PATsecret (see Secrets Management)
Debugging:
# Check workflow runsgh run list --workflow=smart-version-bump.yml --limit 5
# View specific rungh run view <run-id> --logIssue 2: npm Publish Fails
Section titled “Issue 2: npm Publish Fails”Symptoms:
- Release & Publish workflow fails at publish step
- Error: “You cannot publish over the previously published versions”
Possible Causes:
-
Version Already Published
Terminal window npm view @pantheon-ai/opencode-warcraft-notifications@<version>- Solution: This is expected if re-running workflow, no action needed
-
Invalid NPM_TOKEN
- Error: “Unable to authenticate”
- Solution: Regenerate npm token and update secret
-
Package Name Conflict
- Error: “Package name too similar to existing package”
- Solution: Change package name in package.json
Debugging:
# Test npm authentication locallyecho "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrcnpm whoami
# Test publish (dry run)npm publish --dry-runIssue 3: Auto-Merge Not Working
Section titled “Issue 3: Auto-Merge Not Working”Symptoms:
- Version sync PR created
- All checks pass
- PR not auto-merged
Possible Causes:
-
Auto-Merge Not Enabled in Repository
- Check: Settings → General → Pull Requests → Allow auto-merge
- Solution: Enable auto-merge feature
-
Branch Protection Rules
- Required reviews not met
- Required status checks not configured
- Solution: Adjust branch protection rules or add required approvals
-
Auto-Merge Bot Not Running
- Check workflow runs for auto-merge-bot.yml
- Solution: Manually trigger workflow or merge PR
Debugging:
# Check PR statusgh pr view <pr-number> --json autoMergeRequest,mergeable,mergeStateStatus
# Check required status checksgh api repos/:owner/:repo/branches/main/protection/required_status_checksIssue 4: Cycle of Version Bumps
Section titled “Issue 4: Cycle of Version Bumps”Symptoms:
- Multiple version bump commits in quick succession
- Tags created for each commit
- Multiple releases published
Root Cause:
- Cycle prevention not working
- Commit message pattern not matching detection regex
Solution:
-
Check Commit Message Pattern
Terminal window git log --oneline -5- Should contain “chore: bump version” or “[skip ci]”
-
Verify Cycle Prevention Logic
Terminal window # In smart-version-bump.ymlif [[ "$LATEST_COMMIT_MSG" =~ ^chore:\ (bump\ version|sync\ package\.json\ version) ]] -
Manual Intervention
Terminal window # Delete extra tagsgit tag -d v1.0.1 v1.0.2git push origin :refs/tags/v1.0.1 :refs/tags/v1.0.2# Delete extra releases via GitHub UI or APIgh release delete v1.0.1 --yes
Issue 5: Large PR Warning Not Appearing
Section titled “Issue 5: Large PR Warning Not Appearing”Symptoms:
- PR has 20+ files or 500+ lines
- No warning comment posted
Possible Causes:
-
PR Analysis Job Failed
- Check workflow logs for pr-analysis job
- Solution: Fix any errors in the job
-
Insufficient Permissions
- Bot cannot comment on PR
- Solution: Check
GITHUB_TOKENpermissions
-
Comment Already Exists
- Bot doesn’t post duplicate comments
- Solution: This is expected behavior
Debugging:
# Check PR commentsgh pr view <pr-number> --json comments
# Manually trigger PR analysisgh workflow run pr-validation.ymlIssue 6: Trivy Security Scan Failures
Section titled “Issue 6: Trivy Security Scan Failures”Symptoms:
- Security job fails in PR Validation
- SARIF upload errors
Possible Causes:
-
Critical Vulnerabilities Found
- Check Security tab for details
- Solution: Update vulnerable dependencies
-
Trivy Scanner Issues
- Network timeouts
- Scanner version incompatibility
- Solution: Re-run workflow or update Trivy action version
-
SARIF Upload Failures
- Invalid SARIF format
- Solution: Check Trivy output format
Debugging:
# Run Trivy locallydocker run --rm -v $(pwd):/workspace aquasec/trivy:latest fs /workspace
# Validate SARIF filecat trivy-results.sarif | jq .Debugging Workflows
Section titled “Debugging Workflows”View Workflow Logs
Section titled “View Workflow Logs”# List recent workflow runsgh run list --limit 10
# View specific workflow runsgh run list --workflow=pr-validation.yml --limit 5
# View detailed logsgh run view <run-id> --log
# View logs for specific jobgh run view <run-id> --log --job=<job-id>Re-run Failed Workflows
Section titled “Re-run Failed Workflows”# Re-run failed jobs onlygh run rerun <run-id> --failed
# Re-run entire workflowgh run rerun <run-id>Download Workflow Artifacts
Section titled “Download Workflow Artifacts”# List artifactsgh run view <run-id> --json artifacts
# Download artifactgh run download <run-id> --name <artifact-name>Enable Debug Logging
Section titled “Enable Debug Logging”Add secrets to repository:
ACTIONS_RUNNER_DEBUG:true(verbose runner logging)ACTIONS_STEP_DEBUG:true(verbose step logging)
Warning: Generates very large logs, use sparingly.
Emergency Procedures
Section titled “Emergency Procedures”Stop All Workflows
Section titled “Stop All Workflows”# Cancel all running workflowsgh run list --status in_progress --json databaseId --jq '.[].databaseId' | xargs -I {} gh run cancel {}Rollback Release
Section titled “Rollback Release”# Delete tag locally and remotelygit tag -d v1.0.0git push origin :refs/tags/v1.0.0
# Delete GitHub releasegh release delete v1.0.0 --yes
# Unpublish from npm (within 72 hours)npm unpublish @pantheon-ai/opencode-warcraft-notifications@1.0.0Warning: npm unpublish has strict time limits and usage restrictions.
Disable Workflow
Section titled “Disable Workflow”# Add to workflow fileon: workflow_dispatch: # Only manual triggers # Comment out automatic triggers # push: # branches: [main]Best Practices
Section titled “Best Practices”Commit Message Conventions
Section titled “Commit Message Conventions”Conventional Commits Format
Section titled “Conventional Commits Format”<type>(<scope>): <subject>
<body>
<footer>Types:
feat: New feature (triggers MINOR bump)fix: Bug fix (triggers PATCH bump)docs: Documentation only (triggers PATCH bump)style: Formatting, missing semicolons, etc. (triggers PATCH bump)refactor: Code restructuring (triggers PATCH bump)perf: Performance improvement (triggers PATCH bump)test: Adding tests (triggers PATCH bump)chore: Maintenance tasks (triggers PATCH bump)ci: CI/CD changes (may skip version bump)build: Build system changes (may skip version bump)
Breaking Changes:
feat!: remove deprecated API
BREAKING CHANGE: The old API has been removed. Use new API instead.- Triggers MAJOR bump
- Use
!after type orBREAKING CHANGE:in footer
Examples
Section titled “Examples”Good Commit Messages:
feat(notifications): add horde faction support
Implements complete horde sound set with 50+ audio files.Adds faction selection in plugin configuration.
Closes #123fix(sounds): resolve audio playback on macOS
The audio player was failing on macOS due to incorrect file paths.Updated path resolution to use platform-specific separators.
Fixes #456feat!: change plugin configuration schema
BREAKING CHANGE: The configuration format has changed from flatstructure to nested structure. Users must update their config files.
Migration guide: docs/MIGRATION.mdBad Commit Messages:
update stufffix bugWIPasdfPR Best Practices
Section titled “PR Best Practices”PR Size Guidelines
Section titled “PR Size Guidelines”Ideal PR Size:
- Files changed: < 10
- Lines added: < 300
- Lines deleted: < 300
Large PR Thresholds (triggers warning):
- Files changed: > 20
- Lines added: > 500
When Large PRs Are Acceptable:
- Generated code (migrations, schemas)
- Bulk refactoring with automated tools
- Asset additions (sounds, images)
- Documentation updates
PR Description Template
Section titled “PR Description Template”## Description
Brief description of changes
## Type of Change
- [ ] Bug fix (non-breaking change which fixes an issue)- [ ] New feature (non-breaking change which adds functionality)- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)- [ ] Documentation update
## Testing
- [ ] Unit tests added/updated- [ ] Integration tests added/updated- [ ] Manual testing performed
## Checklist
- [ ] Code follows project style guidelines- [ ] Self-review completed- [ ] Comments added for complex logic- [ ] Documentation updated- [ ] No new warnings generated- [ ] Tests pass locallyVersion Bump Strategy
Section titled “Version Bump Strategy”When to Use Each Version Type
Section titled “When to Use Each Version Type”MAJOR (X.0.0):
- Breaking API changes
- Removing features
- Changing behavior that breaks existing usage
- Major architecture changes
MINOR (x.Y.0):
- New features (backwards-compatible)
- New functionality
- Deprecating features (not removing)
- Significant improvements
PATCH (x.y.Z):
- Bug fixes
- Documentation updates
- Performance improvements
- Refactoring (no behavior change)
- Dependency updates
NONE:
- CI/CD changes only
- Formatting/linting fixes
- Test-only changes
- Build configuration
Manual Version Override
Section titled “Manual Version Override”When AI analysis is incorrect:
# Trigger workflow with manual version typegh workflow run smart-version-bump.yml -f version_type=minorUse Cases:
- AI misclassifies breaking change
- Multiple PRs merged, need specific version
- Emergency hotfix requiring specific version
Security Best Practices
Section titled “Security Best Practices”Dependency Management
Section titled “Dependency Management”Regular Updates:
# Check for outdated dependenciesbun outdated
# Update dependenciesbun update
# Update specific packagebun update <package-name>Security Audits:
# Run security auditbun audit
# Fix vulnerabilities automaticallybun audit --fixDependabot Configuration:
version: 2updates: - package-ecosystem: 'npm' directory: '/' schedule: interval: 'weekly' open-pull-requests-limit: 10Secret Rotation
Section titled “Secret Rotation”Schedule:
NPM_TOKEN: Every 90 daysWORKFLOW_PAT: Every 90 daysGOOGLE_AI_API_KEY: Every 180 days
Process:
- Generate new token/key
- Update GitHub secret
- Verify workflow runs successfully
- Revoke old token/key
Code Scanning
Section titled “Code Scanning”Enable GitHub Advanced Security:
- CodeQL analysis
- Secret scanning
- Dependency review
Configuration:
name: 'CodeQL'on: push: branches: [main] pull_request: branches: [main] schedule: - cron: '0 0 * * 1' # WeeklyPerformance Optimization
Section titled “Performance Optimization”Workflow Optimization
Section titled “Workflow Optimization”Parallel Jobs:
jobs: validate: # Runs in parallel with security security: # Runs in parallel with validateConditional Steps:
- name: Upload coverage if: always() # Run even if tests fail
- name: Publish to npm if: steps.check-published.outputs.already_published == 'false'Caching Strategy:
- uses: actions/cache@v4 with: path: ~/.bun/install/cache key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }} restore-keys: | ${{ runner.os }}-bun-Build Optimization
Section titled “Build Optimization”TypeScript Compilation:
{ "compilerOptions": { "incremental": true, "tsBuildInfoFile": ".tsbuildinfo" }}Test Optimization:
# Run tests in parallelbun test --parallel
# Run only changed testsbun test --changedMaintenance
Section titled “Maintenance”Regular Maintenance Tasks
Section titled “Regular Maintenance Tasks”Weekly Tasks
Section titled “Weekly Tasks”- Review workflow run history for failures
- Check security alerts in Security tab
- Review Dependabot PRs
- Verify release cleanup ran successfully
- Check npm package download statistics
Monthly Tasks
Section titled “Monthly Tasks”- Review and update dependencies
- Audit workflow performance metrics
- Review and optimize caching strategies
- Update workflow action versions
- Review and update documentation
Quarterly Tasks
Section titled “Quarterly Tasks”- Rotate secrets (NPM_TOKEN, WORKFLOW_PAT)
- Review and update branch protection rules
- Audit repository configuration
- Review and optimize retention policies
- Conduct security audit
Workflow Updates
Section titled “Workflow Updates”Updating GitHub Actions
Section titled “Updating GitHub Actions”Check for Updates:
# List all actions usedgrep -r "uses:" .github/workflows/ | grep -v "#" | sort -uUpdate Process:
- Check action changelog for breaking changes
- Update version in workflow file
- Test in feature branch
- Merge after validation
Example:
# Before- uses: actions/checkout@v3
# After- uses: actions/checkout@v4Updating Node/Bun Versions
Section titled “Updating Node/Bun Versions”Node.js:
- uses: actions/setup-node@v4 with: node-version: '20' # Update to '22' when LTSBun:
- uses: oven-sh/setup-bun@v2 with: bun-version: 'latest' # Always latestMonitoring Workflow Health
Section titled “Monitoring Workflow Health”Key Metrics to Track
Section titled “Key Metrics to Track”Success Rate:
# Get success rate for last 30 daysgh run list --workflow=pr-validation.yml --created ">$(date -d '30 days ago' +%Y-%m-%d)" --json conclusion | jq '[.[] | .conclusion] | group_by(.) | map({conclusion: .[0], count: length})'Average Duration:
# Get average durationgh run list --workflow=pr-validation.yml --limit 50 --json createdAt,updatedAt | jq '[.[] | ((.updatedAt | fromdateiso8601) - (.createdAt | fromdateiso8601))] | add / length'Failure Analysis:
# List recent failuresgh run list --workflow=pr-validation.yml --status failure --limit 10Performance Benchmarks
Section titled “Performance Benchmarks”Target Metrics:
- PR Validation: < 3 minutes
- Smart Version Bump: < 2 minutes
- Release & Publish: < 5 minutes
- Cleanup workflows: < 30 seconds
Alert Thresholds:
- Duration > 2x target: Investigate
- Success rate < 95%: Investigate
- Consecutive failures > 3: Alert
Disaster Recovery
Section titled “Disaster Recovery”Backup Procedures
Section titled “Backup Procedures”Workflow Files:
# Backup all workflow filestar -czf workflows-backup-$(date +%Y%m%d).tar.gz .github/workflows/Repository Settings:
# Export repository settingsgh api repos/:owner/:repo > repo-settings-$(date +%Y%m%d).jsonSecrets Documentation:
- Maintain encrypted list of all secrets
- Document secret purposes and scopes
- Keep backup of secret values in secure vault
Recovery Procedures
Section titled “Recovery Procedures”Restore Workflow Files:
# Extract backuptar -xzf workflows-backup-20250110.tar.gz
# Commit and pushgit add .github/workflows/git commit -m "chore: restore workflow files from backup"git pushRecreate Secrets:
# Add secret via CLIgh secret set NPM_TOKEN < npm-token.txt
# Or via UI# Settings → Secrets → Actions → New repository secretRebuild Release History:
# If releases were accidentally deleted# Recreate from git tagsfor tag in $(git tag); do gh release create $tag --title "Release $tag" --notes "Restored release"doneAppendix
Section titled “Appendix”Workflow File Reference
Section titled “Workflow File Reference”Complete File Listing
Section titled “Complete File Listing”.github/├── workflows/│ ├── pr-validation.yml # PR quality gates│ ├── smart-version-bump.yml # AI-powered versioning│ ├── sync-package-version.yml # Legacy version sync│ ├── release-publish.yml # npm publishing│ ├── auto-merge-bot.yml # Automated PR merging│ ├── cleanup-merged-branches.yml # Branch cleanup│ ├── cleanup-old-releases.yml # Release cleanup│ └── repo-config-check.yml # Configuration validation├── scripts/│ ├── sync-version.cjs # Version sync logic│ ├── auto-merge.cjs # Auto-merge logic│ └── check-repo-config.cjs # Config check logic└── ISSUE_TEMPLATE/ └── config.yml # Issue template configEnvironment Variables Reference
Section titled “Environment Variables Reference”| Variable | Purpose | Required | Default |
|---|---|---|---|
GITHUB_TOKEN | GitHub API authentication | Yes | Auto-provided |
NPM_TOKEN | npm publishing | Yes | None |
WORKFLOW_PAT | Workflow triggering | No | Falls back to GITHUB_TOKEN |
CODECOV_TOKEN | Coverage upload | No | None |
GOOGLE_AI_API_KEY | AI version analysis | No | None |
ACTIONS_RUNNER_DEBUG | Verbose runner logs | No | false |
ACTIONS_STEP_DEBUG | Verbose step logs | No | false |
npm Scripts Reference
Section titled “npm Scripts Reference”| Script | Command | Purpose |
|---|---|---|
test | bun test src | Run tests |
test:coverage | bun test --coverage src/ | Run tests with coverage |
test:watch | bun test --watch src/ | Watch mode testing |
type-check | bun tsc --noEmit --project tsconfig.test.json | Type checking |
lint | eslint src/ | Linting |
format | prettier --write "**/*.{ts,tsx,js,jsx,json,md,cjs,css}" | Format code |
format:check | prettier --check "**/*.{ts,tsx,js,jsx,json,md,cjs,css}" | Check formatting |
build | bun tsc | Build project |
clean | rm -rf dist/ .bun-cache/ coverage/ | Clean build artifacts |
check:repo-config | node .github/scripts/check-repo-config.cjs | Check repo config |
Useful Commands
Section titled “Useful Commands”GitHub CLI Commands
Section titled “GitHub CLI Commands”# Workflow managementgh workflow listgh workflow view <workflow-name>gh workflow run <workflow-name>gh workflow enable <workflow-name>gh workflow disable <workflow-name>
# Run managementgh run list --workflow=<workflow-name>gh run view <run-id>gh run rerun <run-id>gh run cancel <run-id>gh run watch <run-id>
# PR managementgh pr listgh pr view <pr-number>gh pr checks <pr-number>gh pr merge <pr-number> --squash
# Release managementgh release listgh release view <tag>gh release create <tag>gh release delete <tag>
# Secret managementgh secret listgh secret set <name>gh secret remove <name>Git Commands
Section titled “Git Commands”# Tag managementgit tag -lgit tag -a v1.0.0 -m "Release v1.0.0"git push origin v1.0.0git tag -d v1.0.0git push origin :refs/tags/v1.0.0
# Branch managementgit branch -r --merged origin/maingit push origin --delete <branch-name>
# Commit analysisgit log --oneline --no-mergesgit log --since="2 weeks ago" --onelinegit log --grep="feat:" --onelinenpm Commands
Section titled “npm Commands”# Package informationnpm view @pantheon-ai/opencode-warcraft-notificationsnpm view @pantheon-ai/opencode-warcraft-notifications versionsnpm view @pantheon-ai/opencode-warcraft-notifications@latest
# Publishingnpm publish --dry-runnpm publish --access public --provenance
# Authenticationnpm whoaminpm loginRelated Documentation
Section titled “Related Documentation”- GitHub Workflows Overview - Detailed workflow documentation
- Squash Merge Configuration - Repository setup guide
- Cleanup Old Releases - Release retention policy
- Cycle Prevention Fix - Version bump cycle prevention
- DEPLOYMENT.md - Deployment and installation guide
- DEVELOPMENT.md - Development setup and guidelines
Glossary
Section titled “Glossary”CI/CD: Continuous Integration / Continuous Deployment - Automated software delivery pipeline
Conventional Commits: Standardized commit message format for semantic versioning
Provenance: Cryptographic attestation linking npm package to source code and build process
SARIF: Static Analysis Results Interchange Format - Standard format for security scan results
Semantic Versioning: Version numbering scheme (MAJOR.MINOR.PATCH) based on change significance
Squash Merge: Combining all PR commits into single commit on merge
Trivy: Open-source vulnerability scanner for containers and filesystems
Workflow: Automated process defined in YAML file in .github/workflows/
Document Version: 1.0
Last Updated: 2025-11-10
Maintained By: DevOps Team
For questions or issues with the CI/CD pipeline, please:
- Check this documentation
- Review workflow logs in GitHub Actions
- Search existing issues
- Create new issue with
ci/cdlabel