Skip to content

chore: auto-close linked issues when PRs merge into dev #519

Description

@LeXwDeX

Why

GitHub auto-closes an issue only when a PR carrying Closes #n merges into the default branch (main). This repo's two-tier Git Workflow delivers into dev first (promotion to main happens later via release-sync PRs that carry no per-issue references), so delivery PRs never fire auto-close. Proven by #433/#472/#473/#474/#475/#477/#496: all delivered by merged PRs with intact Closes #n bodies (PRs #480/#482/#485/#486/#487/#491/#497), all left open, all closed manually on 2026-09-03. SpecGit's own #347 closure gate knows this failure mode but only refuses the next bootstrap — it never closes the issues.

Scope

One new GitHub Actions workflow: .github/workflows/dev-issue-autoclose.yml. No product code, no changes to existing workflows (specgit-accept.yml local specializations untouched), no policy changes.

Approach

  • Trigger pull_request: types: [closed]; job guarded by github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'dev'. Merges to main keep GitHub's native auto-close — no overlap.
  • No actions/checkout: the job is pure event-payload + gh API work (also keeps the CodeQL taint surface empty).
  • Least-privilege permissions: contents: read, issues: write, pull-requests: read.
  • Parse the PR body for the official GitHub closing keywords (close/closes/closed/fix/fixes/fixed/resolve/resolves/resolved, case-insensitive) followed by bare #n refs. Qualified (owner/repo#n) and cross-repo URL refs are out of scope — SpecGit writes plain Closes #n.
  • Injection safety: the PR body reaches the script only through env:, never inline ${{ }} interpolation.
  • Guards for the shared issue/PR number space: skip numbers that resolve to a pull request, skip nonexistent numbers, skip already-CLOSED issues (no duplicate comments).
  • Close via gh issue close <n> --reason completed with a comment naming the delivery PR and explaining the dev-layer auto-close mirror.
  • Follow repo workflow conventions: # ==== header block (Purpose/Trigger/Jobs/Notes), emoji name:.

Acceptance

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions