agentskills.codes
PU

push-to-production

Release to production by pushing to main and release branches, verifying Railway auto-deploy, creating a GitHub Release, and transitioning Linear issues. Use when user says "push to production", "release", "deploy to production", or "ship it". Bumps version, updates changelog, pushes to main + relea

Install

mkdir -p .claude/skills/push-to-production && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/13271" && unzip -o skill.zip -d .claude/skills/push-to-production && rm skill.zip

Installs to .claude/skills/push-to-production

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Release to production by pushing to main and release branches, verifying Railway auto-deploy, creating a GitHub Release, and transitioning Linear issues. Use when user says "push to production", "release", "deploy to production", or "ship it". Bumps version, updates changelog, pushes to main + release, verifies Railway deployment, creates GitHub Release, and moves Linear issues to Released.
393 chars✓ has a “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)

About this skill

Release to production. Two Railway environments auto-deploy from different branches:

  • Staging auto-deploys from main
  • Production auto-deploys from release

Both branches must be pushed. The Railway MCP is linked to staging — always specify environment_id: "production" when checking production deployments.

Phase 1: Pre-flight Checks

1.1 Verify Linear MCP

ALWAYS call mcp__linear__list_issues with team: "ADVA Administracion", state: "Done", limit: 250 directly (paginate via cursor if hasNextPage: true). Do NOT try to determine MCP availability by inspecting the tool list, checking settings, or reasoning about it — you MUST actually invoke the tool and check the result. If the call fails or returns an error, warn but do not stop — Linear state transitions are cosmetic, the release can proceed without them.

Record any Done issues for Phase 5.

1.2 Git State

git branch --show-current
git status --porcelain

Requirements:

  • Must be on main branch
  • Working tree must be clean (no uncommitted changes)
  • Must be up to date with remote: git fetch origin && git rev-list --count HEAD..origin/main must be 0

If any check fails, STOP and tell the user what to fix.

1.3 Check for Pending PLANS.md

Read PLANS.md from project root (if it exists). If it contains incomplete tasks (tasks not marked as done), STOP: "There are incomplete tasks in PLANS.md. Finish implementation first or clear the plan before releasing."

If PLANS.md doesn't exist or has no incomplete tasks, continue.

1.4 Build & Tests

Run the verifier agent (full mode) to confirm unit tests, lint, and build pass:

Use the Agent tool with subagent_type "verifier"

If verifier reports failures, STOP. Do not proceed with a broken build.

1.5 Diff Assessment

Check what's being released by examining commits since the last tag:

git describe --tags --abbrev=0
git log <last-tag>..HEAD --oneline
git diff <last-tag>..HEAD --stat

First release (no prior tags): If git describe --tags fails, this is the first tagged release. Use the full commit history and treat the current package.json version as the starting version. Show the user the recent commit list (last ~20 commits).

If there are no commits since the last tag, STOP: "Nothing to release. No commits since last release."

IMPORTANT: Show the user the commit list and file diff summary. Wait for acknowledgment before proceeding to Phase 2.

Phase 2: Version & Changelog

2.1 Determine Version

Follows Semantic Versioning 2.0.0:

  1. Read CHANGELOG.md and extract the current version from the first ## [x.y.z] header. If CHANGELOG.md doesn't exist, this is the first release.
  2. If $ARGUMENTS contains a version (e.g., 2.0.0):
    • Validate it's valid semver (X.Y.Z)
    • Validate it's strictly higher than current version
    • If invalid, STOP: "Invalid version. Must be higher than current [current]."
  3. If no argument, deduce the bump from the commits being released (from Phase 1.5):
    • MAJOR (x+1.0.0): Incompatible/breaking changes — removed or renamed API routes, changed API response shapes, removed features
    • MINOR (x.y+1.0): Backward-compatible new functionality — new document types, new API endpoints, new processing features, significant operational improvements
    • PATCH (x.y.z+1): Backward-compatible bug fixes — bug fixes, extraction accuracy improvements, refactoring, performance improvements, dependency updates
    • When commits span multiple categories, use the highest bump level (MAJOR > MINOR > PATCH)
    • First release: Use the version already in package.json (e.g., 1.0.0)
    • Show the user which version was chosen and why, so they can override if they disagree

2.2 Write Changelog Entry

Follows Keep a Changelog 1.1.0.

See references/changelog-guidelines.md for full INCLUDE/EXCLUDE criteria and writing style rules.

Process:

  1. Review the commit list from Phase 1.5
  2. Determine the net effect against production — use git diff <last-tag>..HEAD --stat (not the commit list) as the source of truth for what actually changed. Commits that introduce and fix the same issue within the cycle, or that rework/remove staging-only code, produce zero changelog entries. The commit list helps understand intent; the diff shows what's actually shipping.
  3. Filter out purely internal changes (they get zero entries)
  4. Move any items from the ## [Unreleased] section into the new version entry
  5. Write a ## [version] - YYYY-MM-DD entry, grouping changes under these section headers (omit empty sections):
    • ### Added — new features, new document types, new API endpoints
    • ### Changed — changes to existing functionality, extraction improvements
    • ### Deprecated — features that will be removed in a future release
    • ### Removed — removed features
    • ### Fixed — bug fixes, extraction accuracy fixes
    • ### Security — security-related changes, vulnerability fixes
  6. Group minor fixes into single items (e.g., "Minor bug fixes" or "Minor extraction accuracy improvements")
  7. Keep each section concise — aim for 3-8 items total across all sections
  8. Insert the new entry between ## [Unreleased] and the previous version (keep Unreleased section empty)
  9. Update the comparison links at the bottom of the file:
    • Discover the repository URL from git remote or CLAUDE.md
    • [Unreleased] link: compare new version tag to HEAD
    • New version link: compare previous version tag to new version tag
    • Format: [Unreleased]: https://github.com/<owner>/<repo>/compare/vNEW...HEAD
    • Format: [NEW]: https://github.com/<owner>/<repo>/compare/vOLD...vNEW
    • First release: Use [NEW]: https://github.com/<owner>/<repo>/commits/vNEW (no previous tag to compare against)

2.3 Update package.json

Edit package.json to set "version" to the new version string. Skip if version already matches.

Phase 3: Commit, Tag & Push

3.1 Commit Release Files

Stage and commit all release housekeeping files:

git add CHANGELOG.md package.json
git commit -m "release: v<version>"

3.2 Tag Release

Create an annotated git tag:

git tag -a "v<version>" -m "v<version>"

3.3 Push to Main and Release

Push the commit and tag to both branches:

git push origin main --follow-tags
git push origin main:release

The first push triggers staging auto-deploy. The second push triggers production auto-deploy.

If either push fails, STOP: "Push failed. Check remote access and try again."

Phase 4: Verify Deployment

4.1 Wait for Production Deployment

Wait briefly (30 seconds) then check production deployment status:

Use mcp__Railway__list_deployments with environment_id: "production"

Look for a deployment that started after the push. Check its status.

4.2 Check Production Deployment Logs

Use Railway MCP to verify the production deployment succeeded:

Use mcp__Railway__get_logs with environment_id: "production"

(log_type: "deploy" is the default; use log_type: "build" to inspect the build.)

Look for:

  • Successful build completion
  • Server startup message (Fastify listening)
  • No crash loops or error patterns

If the deployment appears to have failed:

  • Show the user the relevant log lines
  • Do NOT stop — the git tag and GitHub Release can still proceed. The deployment issue needs separate investigation.
  • Note the failure in the Phase 6 report

4.3 Create GitHub Release

Create a GitHub Release from the tag pushed in Phase 3.2. The release notes come from the changelog entry written in Phase 2.2.

Extract release notes from CHANGELOG.md — the content between the new ## [version] header and the next ## [ header (excluding both headers). This is the same section written in Phase 2.2.

Create the release:

First, write the release notes to a temporary file to avoid multi-line Bash command issues:

Use the Write tool to create release-notes.md with the extracted changelog content

Then create the release using --notes-file (avoids multi-line --notes strings that break Bash permission patterns):

gh release create "v<version>" --title "v<version>" --notes-file release-notes.md --verify-tag

Clean up the temp file after:

rm -f release-notes.md

Flags reference:

  • --verify-tag — Abort if the tag doesn't exist on the remote (safety check)
  • --title — Release title (use the tag name, e.g., v1.12.0)
  • --notes-file — Read release notes from file (preferred over --notes to avoid multi-line Bash issues)
  • Do NOT use --latest — let GitHub auto-detect based on semver (default behavior is correct)
  • Do NOT use --draft or --prerelease — all releases from this skill are production releases

Error handling: If gh release create fails, do NOT stop the release. Log a warning in the Phase 6 report:

**Warning:** GitHub Release creation failed: [error message]. Create manually with:
gh release create "v<version>" --title "v<version>" --notes-file release-notes.md --verify-tag

The git tag and deploy already succeeded — the GitHub Release is cosmetic and can be created manually later.

Phase 5: Linear State Transitions

5.1 Move Done Issues to Released

Transition all Linear issues in "Done" to "Released" now that the code is live in production.

  1. Use the Done issues already fetched in Phase 1.1. If that call failed, try again now:

    mcp__linear__list_issues with team: "ADVA Administracion", state: "Done", limit: 250
    

    If the response has hasNextPage: true, keep fetching with the returned cursor until all Done issues are collected.

  2. Look up the Released state UUID using mcp__linear__list_issue_statuses with team "AD


Content truncated.

Search skills

Search the agent skills registry