Skip to content

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.

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.

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
#WorkflowTriggerDurationPurpose
1Validate PRPull Request~2-3 minQuality assurance (lint, test, build)
2Publish ReleaseTag push (v*)~3-4 minPublish npm, docs, GitHub release
3CleanupAfter publish~30 secDelete old branches and releases
-Release PleasePR merge to main~1-2 minCreate release PR with changelog
-Deploy DocumentationPush to main (docs)~30 secIndependent docs deployment
-Repo Config CheckSchedule, Manual~10 secConfiguration validation

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

Purpose: Maintain repository hygiene
Frequency: Event-driven + Weekly


File: .github/workflows/pr-validation.yml
Purpose: Comprehensive quality assurance for all pull requests

on:
pull_request:
branches: [main, develop]
types: [opened, synchronize, reopened]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

Behavior: Cancels in-progress runs when new commits are pushed to the same PR.

Purpose: Code quality validation
Runner: ubuntu-latest
Timeout: Default (360 minutes)

  1. Checkout Repository

    - uses: actions/checkout@v4
    with:
    fetch-depth: 0 # Full history for accurate analysis
  2. Setup Bun Runtime

    - uses: oven-sh/setup-bun@v2
    with:
    bun-version: 'latest'
    • Why Bun?: Faster package installation and test execution
    • Version Strategy: Always use latest for development
  3. Cache Dependencies

    - uses: actions/cache@v4
    with:
    path: ~/.bun/install/cache
    key: ${{ 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
  4. Install Dependencies

    Terminal window
    bun install --frozen-lockfile
    • Frozen Lockfile: Ensures reproducible builds
    • Fails if: lockfile is out of sync with package.json
  5. Format Check

    Terminal window
    bun run format:check
    • Tool: Prettier
    • Config: .prettierrc
    • Scope: All TypeScript, JavaScript, JSON, Markdown files
  6. Linting

    Terminal window
    bun run lint
    • Tool: ESLint
    • Config: eslint.config.cjs
    • Rules: TypeScript, Import, JSDoc, SonarJS, Prettier integration
  7. Type Checking

    Terminal window
    bun run type-check
    • Tool: TypeScript Compiler
    • Config: tsconfig.test.json
    • Mode: No emit, type checking only
  8. Test with Coverage

    Terminal window
    bun run test:coverage
    • Framework: Bun’s built-in test runner
    • Coverage: Enabled
    • Scope: src/ directory
  9. Build Project

    Terminal window
    bun run build
    • Tool: TypeScript Compiler
    • Output: Compiled JavaScript
    • Validation: Ensures production build succeeds
  10. Upload Coverage

    - uses: codecov/codecov-action@v4
    if: always()
    with:
    token: ${{ secrets.CODECOV_TOKEN }}
    fail_ci_if_error: false
    • Service: Codecov
    • Behavior: Always runs, even if tests fail
    • Failure Mode: Non-blocking

Purpose: Vulnerability scanning
Runner: ubuntu-latest

  1. Trivy Vulnerability Scanner

    - uses: aquasecurity/trivy-action@master
    with:
    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)
  2. Upload SARIF Results

    - uses: github/codeql-action/upload-sarif@v3
    if: always()
    with:
    sarif_file: 'trivy-results.sarif'
    • Integration: GitHub Security tab
    • Visibility: Security alerts visible in PR and repository

Purpose: Analyze PR size and complexity
Runner: ubuntu-latest

  1. 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}')
  2. Large PR Detection

    • Threshold: 20+ files OR 500+ added lines
    • Action: Post warning comment
  3. 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**...`,
    });

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

File: .github/workflows/smart-version-bump.yml
Purpose: AI-powered semantic versioning with cross-validation

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:
group: version-bump-${{ github.ref }}
cancel-in-progress: false # Never cancel version bumps

Critical: Version bumps must complete to prevent state inconsistencies.

Purpose: Determine appropriate version bump
Runner: ubuntu-latest

Terminal window
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 0
fi

Prevents: Infinite loop of version bump commits triggering more version bumps.

  1. Get Commits Since Last Tag

    Terminal window
    LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
    if [ -z "$LATEST_TAG" ]; then
    COMMITS=$(git log --oneline --no-merges)
    else
    COMMITS=$(git log ${LATEST_TAG}..HEAD --oneline --no-merges)
    fi
  2. Squash Merge Detection

    Terminal window
    COMMIT_COUNT=$(echo "$COMMITS" | wc -l)
    if [ "$COMMIT_COUNT" -eq 1 ]; then
    echo "✅ Single commit detected (likely squash merge)"
    fi
  1. Install Gemini CLI

    Terminal window
    curl -o- https://generativelanguage.googleapis.com/install.sh | bash
  2. 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
  3. 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:]')

If AI fails or returns invalid response:

Terminal window
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"
fi
Terminal window
# Independent conventional commit analysis
if grep -qi "BREAKING CHANGE\|!:" commits.txt; then
CONVENTIONAL_DECISION="MAJOR"
elif grep -qi "^feat\|^feature" commits.txt; then
CONVENTIONAL_DECISION="MINOR"
# ... etc
fi
# Compare decisions
if [ "$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"
fi
fi

Safety Mechanism: Always chooses the higher semantic version level when there’s disagreement.

Terminal window
# Calculate new version based on latest tag
IFS='.' 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}"

Purpose: Apply version bump and create release tag
Runner: ubuntu-latest
Depends On: analyze-changes

Terminal window
if git tag -l "v$NEW_VERSION" | grep -q "v$NEW_VERSION"; then
echo "⚠️ Tag v$NEW_VERSION already exists locally - skipping"
exit 0
elif git ls-remote --tags origin | grep -q "refs/tags/v$NEW_VERSION$"; then
echo "⚠️ Tag v$NEW_VERSION already exists on remote - skipping"
exit 0
fi

Prevents: Duplicate tags from workflow re-runs.

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');
Terminal window
git add package.json
git 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 --tags
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 }}

File: .github/workflows/sync-package-version.yml
Purpose: Legacy workflow for version synchronization (mostly obsolete with Smart Version Bump)

on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
tag:
description: 'Tag to sync (e.g., v1.2.3)'
required: true
type: string

Purpose: Determine if package.json needs updating
Runner: ubuntu-latest

Terminal window
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_OUTPUT
else
echo "📦 Package.json needs sync (legacy mode)"
echo "sync_needed=true" >> $GITHUB_OUTPUT
fi

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.


File: .github/workflows/release-publish.yml
Purpose: Build, test, and publish package to npm with provenance

on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
tag:
description: 'Tag to publish (e.g., v1.2.3)'
required: true
type: string
permissions:
contents: write # Create releases
id-token: write # npm provenance

Provenance: Enables npm package provenance for supply chain security.

Purpose: Complete release pipeline
Runner: ubuntu-latest

Terminal window
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 1
fi

Critical: Ensures package.json and tag are in sync before publishing.

Terminal window
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 build

Quality Gate: All must pass before publishing.

Terminal window
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"
fi

Idempotency: Prevents duplicate publications.

Terminal window
npm publish --access public --provenance

Flags:

  • --access public: Package is publicly accessible
  • --provenance: Generates provenance attestation linking package to source
// Get or create release
let 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 info
const 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
`;
Terminal window
# Wait for npm to propagate with retry logic
for 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
fi
done

Retry Logic: 6 attempts with 15-second delays (90 seconds total).


File: .github/workflows/auto-merge-bot.yml
Purpose: Automatically merge version sync PRs after validation

on:
pull_request:
types: [opened, synchronize, reopened]
check_suite:
types: [completed]
workflow_run:
workflows: ['PR Validation']
types: [completed]
// Extract PR number based on event type
let 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;
}
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';
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',
);
Terminal window
gh pr merge ${prNumber} --squash --auto --delete-branch

Flags:

  • --squash: Enforce single commit per merge
  • --auto: Enable auto-merge when checks pass
  • --delete-branch: Clean up after merge

File: .github/workflows/cleanup-merged-branches.yml
Purpose: Automatic branch cleanup after PR merge

on:
pull_request:
types: [closed]
schedule:
- cron: '0 2 * * 0' # Weekly on Sundays at 2 AM UTC
workflow_dispatch:
Terminal window
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"
fi
Terminal window
# Get all remote branches that have been merged into main
MERGED_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"
done

Safety Features:

  • Skips protected branches (main, master, develop, staging, production)
  • Only deletes branches older than 1 day
  • Only deletes branches merged into main

File: .github/workflows/cleanup-old-releases.yml
Purpose: Maintain manageable release history

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*'
// Keep up to 5 major versions
const majorsToKeep = majorVersions.slice(0, 5);
// For current major: keep up to 10 minor/patch releases
if (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 release
else {
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
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)

File: .github/workflows/deploy-docs.yml
Purpose: Build and deploy documentation to GitHub Pages using Astro’s official action

The documentation deployment workflow uses GitHub Actions with the official Astro action:

  • main branch: Contains source markdown files and build configuration
  • Artifact-based deployment: No separate branch needed - uses GitHub Pages artifacts
  • Astro action: Uses withastro/action@v3 for optimized builds and deployment

This approach ensures clean version control history, faster builds, and automated documentation deployment.

on:
push:
branches: [main]
paths:
- 'docs/**'
- 'pages/**'
release:
types: [published]
workflow_dispatch:

Trigger Conditions:

  • Pushes to main branch that modify docs/** or pages/** directories
  • New releases are published
  • Manual workflow dispatch
permissions:
contents: read
pages: write
id-token: write

Critical: The workflow needs pages: write and id-token: write permissions for GitHub Pages deployment.

concurrency:
group: 'pages'
cancel-in-progress: false

Behavior: Only one documentation deployment runs at a time. New deployments wait for current deployment to complete (no cancellation).

Purpose: Build static site and upload as artifact
Runner: ubuntu-latest
Duration: 2-5 minutes

  1. Checkout Repository

    - name: Checkout repository
    uses: actions/checkout@v4
    with:
    fetch-depth: 0 # Full history for accurate build
  2. Setup Bun Runtime

    - name: Setup Bun
    uses: oven-sh/setup-bun@v2
    with:
    bun-version: latest
    • Why Bun?: 10-20x faster package installation than npm
    • Version Strategy: Always use latest for documentation builds
  3. Install Dependencies

    Terminal window
    cd pages
    bun install --frozen-lockfile
    • Installs Astro, Starlight, and all documentation dependencies
    • Uses bun.lock for reproducible builds
  4. Install Playwright Browsers

    Terminal window
    cd pages
    bunx playwright install --with-deps chromium
    • Required for link verification and testing
  5. Transform Documentation

    Terminal window
    cd pages
    node transform-docs.js
    • Syncs markdown files from ./docs/ to ./pages/src/content/docs/
  6. Build and Upload with Astro Action

    - name: Build and upload with Astro action
    uses: withastro/action@v3
    with:
    path: ./pages
    package-manager: bun@latest

    Action Benefits:

    • Optimized Astro builds with caching
    • Automatic artifact upload to GitHub Pages
    • Built-in error handling
    • Official Astro support
  7. Verify Internal Links

    Terminal window
    cd pages
    bun run verify
    • Validates all internal links in the built site
    • Prevents broken links from being deployed

Purpose: Deploy built artifacts to GitHub Pages
Runner: ubuntu-latest
Duration: 30 seconds

  1. Deploy to GitHub Pages

    - name: Deploy to GitHub Pages
    id: deployment
    uses: actions/deploy-pages@v4
    • Deploys the artifact uploaded by the build job
    • Creates/updates the github-pages environment
    • Returns the deployment URL
  2. Generate Summary

    • Creates a deployment summary with URL, commit SHA, and build details
    • Visible in the GitHub Actions workflow run

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 mappings

Note: No separate branch is created - artifacts are stored in GitHub Pages service.

After first workflow run, configure GitHub Pages:

  1. Go to: Settings → Pages
  2. Set Source: GitHub Actions
  3. Click Save (if required)

URL: https://pantheon-org.github.io/opencode-warcraft-notifications/

Workflow Status:

Terminal window
# List recent documentation deployments
gh run list --workflow=deploy-docs.yml --limit 5
# View specific run
gh run view <run-id> --log
# Watch current run
gh run watch

Deployment Verification:

Terminal window
# Verify site is accessible
curl -I https://pantheon-org.github.io/opencode-warcraft-notifications/
# Check deployment status
gh api repos/:owner/:repo/pages/deployments --jq '.[0]'
# View environment deployments
gh api repos/:owner/:repo/environments/github-pages/deployments --jq '.[]| {created_at, environment, state}'

Issue 1: Deployment not triggered

Symptoms: Workflow completes but no deployment occurs

Solution:

  1. Check workflow logs for errors
  2. Verify pages: write and id-token: write permissions in workflow
  3. Check repository Actions permissions (Settings → Actions → General)
  4. Verify GitHub Pages source is set to “GitHub Actions” (Settings → Pages)
  5. Manually trigger workflow: Actions → Deploy Documentation → Run workflow

Issue 2: GitHub Pages not updating

Symptoms: Site shows old content after deployment

Solution:

  1. Verify GitHub Pages source is set to “GitHub Actions” (not a branch)
  2. Check deployment status: Repository → Environments → github-pages
  3. Hard refresh browser: Ctrl+Shift+R (Windows/Linux) or Cmd+Shift+R (Mac)
  4. Wait 1-2 minutes for GitHub Pages propagation
  5. Check workflow summary for deployment URL

Issue 3: Build failures

Symptoms: Workflow fails during build step

Solution:

  1. Check workflow logs for specific error
  2. Verify all markdown files have valid frontmatter
  3. Check for broken internal links (link verification step)
  4. Test build locally: cd pages && bun install && bun run build
  5. Verify dependencies are up to date in pages/bun.lock

Issue 4: Link verification failures

Symptoms: Workflow fails at “Verify internal links” step

Solution:

  1. Run link verification locally: cd pages && bun run verify
  2. Fix any broken internal links in source markdown files
  3. Ensure all referenced files exist in ./docs/
  4. Re-run the workflow after fixing links

Issue 5: Permission denied errors

Symptoms: “Permission denied” or “Resource not accessible”

Solution:

  1. Verify workflow has pages: write and id-token: write permissions
  2. Check repository Actions permissions:
    • Settings → Actions → General
    • Workflow permissions → “Read and write permissions”
  3. Verify GITHUB_TOKEN is available in workflow
  • 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)

File: .github/workflows/repo-config-check.yml
Purpose: Validate repository settings for single-release-per-PR

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”
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
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)
...`,
});
}

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

Version: 20.x
Purpose: npm publishing compatibility

- uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://registry.npmjs.org'
always-auth: true

Why Node 20?

  • LTS version with long-term support
  • Required for npm provenance
  • Stable npm CLI
- 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

Purpose: Authenticate npm publishing
Type: npm Access Token
Scope: Automation (publish-only)

Setup:

  1. Go to npmjs.com → Account Settings → Access Tokens
  2. Generate new token with “Automation” type
  3. Add to GitHub: Settings → Secrets → Actions → New repository secret
  4. Name: NPM_TOKEN

Security:

  • ✅ Automation tokens cannot be used for login
  • ✅ Can be revoked without affecting other tokens
  • ✅ Scoped to specific packages

Purpose: Enable workflow-to-workflow triggering
Type: Personal Access Token (Classic)
Scope: repo, workflow

Why Needed?

  • Default GITHUB_TOKEN cannot trigger other workflows (security feature)
  • Smart Version Bump needs to trigger Release & Publish
  • Without PAT: Manual intervention required

Setup:

  1. Go to GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic)
  2. Generate new token with scopes: repo, workflow
  3. Add to repository: Settings → Secrets → Actions → New repository secret
  4. Name: WORKFLOW_PAT

Security Considerations:

  • ⚠️ PAT has broader permissions than GITHUB_TOKEN
  • ✅ Use fine-grained tokens when available
  • ✅ Set expiration date
  • ✅ Regularly rotate tokens

Purpose: Upload coverage reports to Codecov
Type: Codecov Upload Token
Required: No (workflow continues without it)

Setup:

  1. Go to codecov.io → Repository Settings
  2. Copy upload token
  3. Add to GitHub secrets as CODECOV_TOKEN

Purpose: Enable AI-powered version analysis
Type: Google AI (Gemini) API Key
Required: No (falls back to conventional commits)

Setup:

  1. Go to Google AI Studio
  2. Generate API key
  3. Add to GitHub secrets as GOOGLE_AI_API_KEY

Fallback Behavior:

  • If missing or invalid: Uses conventional commit analysis only
  • No workflow failure
- 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 missing
Terminal window
if [ -z "${{ secrets.NPM_TOKEN }}" ]; then
echo "❌ NPM_TOKEN secret is required for publishing"
exit 1
fi

Location: Repository → Actions tab

Key Metrics:

  • Workflow run status (success/failure/cancelled)
  • Run duration
  • Job-level status
  • Step-level logs

Add to README.md:

![PR Validation](https://github.com/pantheon-org/opencode-warcraft-notifications/actions/workflows/pr-validation.yml/badge.svg)
![Release & Publish](https://github.com/pantheon-org/opencode-warcraft-notifications/actions/workflows/release-publish.yml/badge.svg)

Dashboard: codecov.io/gh/pantheon-org/opencode-warcraft-notifications

Metrics:

  • Overall coverage percentage
  • Coverage trends over time
  • File-level coverage
  • PR coverage diff

Badge:

[![codecov](https://codecov.io/gh/pantheon-org/opencode-warcraft-notifications/branch/main/graph/badge.svg)](https://codecov.io/gh/pantheon-org/opencode-warcraft-notifications)

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

URL: https://www.npmjs.com/package/@pantheon-ai/opencode-warcraft-notifications

Metrics:

  • Download statistics
  • Version history
  • Provenance information
  • Package size
Terminal window
npm view @pantheon-ai/opencode-warcraft-notifications@latest --json | jq .dist.attestations

Verifies:

  • Package built by GitHub Actions
  • Source repository linkage
  • Build environment integrity

Location: Repository → Releases

Information:

  • Release notes
  • npm package links
  • Build information
  • Download statistics

Automatic Notifications For:

  • Workflow failures
  • Security alerts
  • PR comments (large PR warnings)
  • Auto-merge status

Configuration: Settings → Notifications

Setup: GitHub account settings → Notifications → Email preferences

Recommended:

  • ✅ Workflow failures
  • ✅ Security alerts
  • ❌ Workflow successes (too noisy)

Symptoms:

  • PR merged to main
  • No version bump workflow run
  • No new tag created

Possible Causes:

  1. Workflow-Generated Commit

    Terminal window
    # Check latest commit message
    git log -1 --pretty=format:"%s"
    • If contains “chore: bump version” or “[skip ci]”: Cycle prevention activated
    • Solution: This is expected behavior, no action needed
  2. Path Filters Excluding Changes

    paths-ignore:
    - '.github/**'
    - 'docs/**'
    - '*.md'
    • If only these paths changed: Workflow skipped
    • Solution: Make substantive code changes
  3. Missing WORKFLOW_PAT

    • Smart Version Bump runs but doesn’t trigger Release & Publish
    • Solution: Add WORKFLOW_PAT secret (see Secrets Management)

Debugging:

Terminal window
# Check workflow runs
gh run list --workflow=smart-version-bump.yml --limit 5
# View specific run
gh run view <run-id> --log

Symptoms:

  • Release & Publish workflow fails at publish step
  • Error: “You cannot publish over the previously published versions”

Possible Causes:

  1. Version Already Published

    Terminal window
    npm view @pantheon-ai/opencode-warcraft-notifications@<version>
    • Solution: This is expected if re-running workflow, no action needed
  2. Invalid NPM_TOKEN

    • Error: “Unable to authenticate”
    • Solution: Regenerate npm token and update secret
  3. Package Name Conflict

    • Error: “Package name too similar to existing package”
    • Solution: Change package name in package.json

Debugging:

Terminal window
# Test npm authentication locally
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc
npm whoami
# Test publish (dry run)
npm publish --dry-run

Symptoms:

  • Version sync PR created
  • All checks pass
  • PR not auto-merged

Possible Causes:

  1. Auto-Merge Not Enabled in Repository

    • Check: Settings → General → Pull Requests → Allow auto-merge
    • Solution: Enable auto-merge feature
  2. Branch Protection Rules

    • Required reviews not met
    • Required status checks not configured
    • Solution: Adjust branch protection rules or add required approvals
  3. Auto-Merge Bot Not Running

    • Check workflow runs for auto-merge-bot.yml
    • Solution: Manually trigger workflow or merge PR

Debugging:

Terminal window
# Check PR status
gh pr view <pr-number> --json autoMergeRequest,mergeable,mergeStateStatus
# Check required status checks
gh api repos/:owner/:repo/branches/main/protection/required_status_checks

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:

  1. Check Commit Message Pattern

    Terminal window
    git log --oneline -5
    • Should contain “chore: bump version” or “[skip ci]”
  2. Verify Cycle Prevention Logic

    Terminal window
    # In smart-version-bump.yml
    if [[ "$LATEST_COMMIT_MSG" =~ ^chore:\ (bump\ version|sync\ package\.json\ version) ]]
  3. Manual Intervention

    Terminal window
    # Delete extra tags
    git tag -d v1.0.1 v1.0.2
    git push origin :refs/tags/v1.0.1 :refs/tags/v1.0.2
    # Delete extra releases via GitHub UI or API
    gh release delete v1.0.1 --yes

Symptoms:

  • PR has 20+ files or 500+ lines
  • No warning comment posted

Possible Causes:

  1. PR Analysis Job Failed

    • Check workflow logs for pr-analysis job
    • Solution: Fix any errors in the job
  2. Insufficient Permissions

    • Bot cannot comment on PR
    • Solution: Check GITHUB_TOKEN permissions
  3. Comment Already Exists

    • Bot doesn’t post duplicate comments
    • Solution: This is expected behavior

Debugging:

Terminal window
# Check PR comments
gh pr view <pr-number> --json comments
# Manually trigger PR analysis
gh workflow run pr-validation.yml

Symptoms:

  • Security job fails in PR Validation
  • SARIF upload errors

Possible Causes:

  1. Critical Vulnerabilities Found

    • Check Security tab for details
    • Solution: Update vulnerable dependencies
  2. Trivy Scanner Issues

    • Network timeouts
    • Scanner version incompatibility
    • Solution: Re-run workflow or update Trivy action version
  3. SARIF Upload Failures

    • Invalid SARIF format
    • Solution: Check Trivy output format

Debugging:

Terminal window
# Run Trivy locally
docker run --rm -v $(pwd):/workspace aquasec/trivy:latest fs /workspace
# Validate SARIF file
cat trivy-results.sarif | jq .
Terminal window
# List recent workflow runs
gh run list --limit 10
# View specific workflow runs
gh run list --workflow=pr-validation.yml --limit 5
# View detailed logs
gh run view <run-id> --log
# View logs for specific job
gh run view <run-id> --log --job=<job-id>
Terminal window
# Re-run failed jobs only
gh run rerun <run-id> --failed
# Re-run entire workflow
gh run rerun <run-id>
Terminal window
# List artifacts
gh run view <run-id> --json artifacts
# Download artifact
gh run download <run-id> --name <artifact-name>

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.

Terminal window
# Cancel all running workflows
gh run list --status in_progress --json databaseId --jq '.[].databaseId' | xargs -I {} gh run cancel {}
Terminal window
# Delete tag locally and remotely
git tag -d v1.0.0
git push origin :refs/tags/v1.0.0
# Delete GitHub release
gh release delete v1.0.0 --yes
# Unpublish from npm (within 72 hours)
npm unpublish @pantheon-ai/opencode-warcraft-notifications@1.0.0

Warning: npm unpublish has strict time limits and usage restrictions.

# Add to workflow file
on:
workflow_dispatch: # Only manual triggers
# Comment out automatic triggers
# push:
# branches: [main]

<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 or BREAKING CHANGE: in footer

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 #123
fix(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 #456
feat!: change plugin configuration schema
BREAKING CHANGE: The configuration format has changed from flat
structure to nested structure. Users must update their config files.
Migration guide: docs/MIGRATION.md

Bad Commit Messages:

update stuff
fix bug
WIP
asdf

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
## 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 locally

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

When AI analysis is incorrect:

Terminal window
# Trigger workflow with manual version type
gh workflow run smart-version-bump.yml -f version_type=minor

Use Cases:

  • AI misclassifies breaking change
  • Multiple PRs merged, need specific version
  • Emergency hotfix requiring specific version

Regular Updates:

Terminal window
# Check for outdated dependencies
bun outdated
# Update dependencies
bun update
# Update specific package
bun update <package-name>

Security Audits:

Terminal window
# Run security audit
bun audit
# Fix vulnerabilities automatically
bun audit --fix

Dependabot Configuration:

.github/dependabot.yml
version: 2
updates:
- package-ecosystem: 'npm'
directory: '/'
schedule:
interval: 'weekly'
open-pull-requests-limit: 10

Schedule:

  • NPM_TOKEN: Every 90 days
  • WORKFLOW_PAT: Every 90 days
  • GOOGLE_AI_API_KEY: Every 180 days

Process:

  1. Generate new token/key
  2. Update GitHub secret
  3. Verify workflow runs successfully
  4. Revoke old token/key

Enable GitHub Advanced Security:

  • CodeQL analysis
  • Secret scanning
  • Dependency review

Configuration:

.github/workflows/codeql-analysis.yml
name: 'CodeQL'
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '0 0 * * 1' # Weekly

Parallel Jobs:

jobs:
validate:
# Runs in parallel with security
security:
# Runs in parallel with validate

Conditional 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-

TypeScript Compilation:

{
"compilerOptions": {
"incremental": true,
"tsBuildInfoFile": ".tsbuildinfo"
}
}

Test Optimization:

Terminal window
# Run tests in parallel
bun test --parallel
# Run only changed tests
bun test --changed

  • 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
  • Review and update dependencies
  • Audit workflow performance metrics
  • Review and optimize caching strategies
  • Update workflow action versions
  • Review and update documentation
  • Rotate secrets (NPM_TOKEN, WORKFLOW_PAT)
  • Review and update branch protection rules
  • Audit repository configuration
  • Review and optimize retention policies
  • Conduct security audit

Check for Updates:

Terminal window
# List all actions used
grep -r "uses:" .github/workflows/ | grep -v "#" | sort -u

Update Process:

  1. Check action changelog for breaking changes
  2. Update version in workflow file
  3. Test in feature branch
  4. Merge after validation

Example:

# Before
- uses: actions/checkout@v3
# After
- uses: actions/checkout@v4

Node.js:

- uses: actions/setup-node@v4
with:
node-version: '20' # Update to '22' when LTS

Bun:

- uses: oven-sh/setup-bun@v2
with:
bun-version: 'latest' # Always latest

Success Rate:

Terminal window
# Get success rate for last 30 days
gh 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:

Terminal window
# Get average duration
gh run list --workflow=pr-validation.yml --limit 50 --json createdAt,updatedAt | jq '[.[] | ((.updatedAt | fromdateiso8601) - (.createdAt | fromdateiso8601))] | add / length'

Failure Analysis:

Terminal window
# List recent failures
gh run list --workflow=pr-validation.yml --status failure --limit 10

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

Workflow Files:

Terminal window
# Backup all workflow files
tar -czf workflows-backup-$(date +%Y%m%d).tar.gz .github/workflows/

Repository Settings:

Terminal window
# Export repository settings
gh api repos/:owner/:repo > repo-settings-$(date +%Y%m%d).json

Secrets Documentation:

  • Maintain encrypted list of all secrets
  • Document secret purposes and scopes
  • Keep backup of secret values in secure vault

Restore Workflow Files:

Terminal window
# Extract backup
tar -xzf workflows-backup-20250110.tar.gz
# Commit and push
git add .github/workflows/
git commit -m "chore: restore workflow files from backup"
git push

Recreate Secrets:

Terminal window
# Add secret via CLI
gh secret set NPM_TOKEN < npm-token.txt
# Or via UI
# Settings → Secrets → Actions → New repository secret

Rebuild Release History:

Terminal window
# If releases were accidentally deleted
# Recreate from git tags
for tag in $(git tag); do
gh release create $tag --title "Release $tag" --notes "Restored release"
done

.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 config
VariablePurposeRequiredDefault
GITHUB_TOKENGitHub API authenticationYesAuto-provided
NPM_TOKENnpm publishingYesNone
WORKFLOW_PATWorkflow triggeringNoFalls back to GITHUB_TOKEN
CODECOV_TOKENCoverage uploadNoNone
GOOGLE_AI_API_KEYAI version analysisNoNone
ACTIONS_RUNNER_DEBUGVerbose runner logsNofalse
ACTIONS_STEP_DEBUGVerbose step logsNofalse
ScriptCommandPurpose
testbun test srcRun tests
test:coveragebun test --coverage src/Run tests with coverage
test:watchbun test --watch src/Watch mode testing
type-checkbun tsc --noEmit --project tsconfig.test.jsonType checking
linteslint src/Linting
formatprettier --write "**/*.{ts,tsx,js,jsx,json,md,cjs,css}"Format code
format:checkprettier --check "**/*.{ts,tsx,js,jsx,json,md,cjs,css}"Check formatting
buildbun tscBuild project
cleanrm -rf dist/ .bun-cache/ coverage/Clean build artifacts
check:repo-confignode .github/scripts/check-repo-config.cjsCheck repo config
Terminal window
# Workflow management
gh workflow list
gh workflow view <workflow-name>
gh workflow run <workflow-name>
gh workflow enable <workflow-name>
gh workflow disable <workflow-name>
# Run management
gh 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 management
gh pr list
gh pr view <pr-number>
gh pr checks <pr-number>
gh pr merge <pr-number> --squash
# Release management
gh release list
gh release view <tag>
gh release create <tag>
gh release delete <tag>
# Secret management
gh secret list
gh secret set <name>
gh secret remove <name>
Terminal window
# Tag management
git tag -l
git tag -a v1.0.0 -m "Release v1.0.0"
git push origin v1.0.0
git tag -d v1.0.0
git push origin :refs/tags/v1.0.0
# Branch management
git branch -r --merged origin/main
git push origin --delete <branch-name>
# Commit analysis
git log --oneline --no-merges
git log --since="2 weeks ago" --oneline
git log --grep="feat:" --oneline
Terminal window
# Package information
npm view @pantheon-ai/opencode-warcraft-notifications
npm view @pantheon-ai/opencode-warcraft-notifications versions
npm view @pantheon-ai/opencode-warcraft-notifications@latest
# Publishing
npm publish --dry-run
npm publish --access public --provenance
# Authentication
npm whoami
npm login

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:

  1. Check this documentation
  2. Review workflow logs in GitHub Actions
  3. Search existing issues
  4. Create new issue with ci/cd label