Skip to content

Add release engineering for library CI and seed templates - #3

Merged
jeremy merged 17 commits into
mainfrom
releng
Mar 5, 2026
Merged

Add release engineering for library CI and seed templates#3
jeremy merged 17 commits into
mainfrom
releng

Conversation

@jeremy

@jeremy jeremy commented Mar 5, 2026

Copy link
Copy Markdown
Member

Summary

  • This repo's CI/CD: GitHub Actions workflows (test, security, release, dependabot-auto-merge), Makefile targets (tidy-check, vuln, secrets, security, release-check, release), pre-commit hooks, release script, RELEASING.md, toolchain pin, GitHub config (dependabot, CODEOWNERS, CodeQL, changelog categories)
  • Seed templates: Full GitHub infra layer so new CLIs get the complete releng stack from day one — 6 workflows (test/7 jobs, security/5 jobs, release with 6 feature-flag guards, AI labeler, dependabot, labeler), scripts (release, surface check, PGO profiling), AI prompts (PR classification, breaking change detection, changelog generation), config templates (pre-commit, gitleaks, RELEASING.md), enhanced Makefile with 15+ new targets
  • Bootstrap prompt: Updated seed-cli.md with all new files, fixed skills template path bug, added GitHub infra setup and secrets configuration docs

All optional features degrade gracefully with zero secrets. All actions SHA-pinned, explicit least-privilege permissions on every workflow. Passes actionlint, shellcheck, and make check.

Test plan

  • make check passes (Go 1.26.0)
  • actionlint .github/workflows/*.yml exits 0
  • actionlint seed/.github/workflows/*.yml exits 0
  • shellcheck scripts/*.sh seed/scripts/*.sh exits 0
  • All 10 workflows have explicit permissions: blocks
  • All third-party uses: refs are SHA-pinned
  • No secrets.* in any if: condition
  • Feature-flag guards verified (vars, env-var indirection for macOS/AUR)
  • .tmpl files render cleanly with fixture values, no unresolved markers

jeremy added 9 commits March 4, 2026 17:51
Add tidy-check, vuln, secrets, security, release-check, and release
targets to support the full CI quality gate and local release workflow.
- test.yml: 4 jobs (test, lint, govulncheck, race detection)
- security.yml: 5 jobs (gitleaks, trivy, gosec, dependency-review, CodeQL)
- release.yml: tag-triggered library release with guarded skills sync
- dependabot-auto-merge.yml: auto-merge minor/patch dependency updates

All actions SHA-pinned, explicit least-privilege permissions throughout.
- dependabot.yml: weekly Go + Actions updates with cooldown settings
- CODEOWNERS: actions/, seed/, workflows/, scripts/ owned by @basecamp/sip
- release.yml: changelog categories with dependabot exclusion
- codeql-config.yml: security-and-quality query suite
- .pre-commit-config.yaml: golangci-lint, gitleaks, go mod tidy, test
- scripts/release.sh: semver validation, quality gate, annotated tag
- RELEASING.md: library release process and CI secrets documentation
- .mise.toml: pin Go toolchain to prevent version mismatch
Add tidy-check, check-naming, replace-check, check-surface, vuln,
secrets, security, provenance-check, release-check, release,
sync-skills, collect-profile, and build-pgo targets for consumer CLIs.
- release.sh.tmpl: semver validation, quality gate, tag + push
- check-cli-surface.sh: --help --agent JSON surface snapshot
- check-cli-surface-diff.sh: diff two snapshots, fail on removals
- collect-profile.sh: PGO profile collection from benchmarks
- sync-skills.sh: fix SC2231 quoting in glob expansion
- test.yml: 7 jobs (test, lint, govulncheck, race, BATS, surface, benchmarks)
- security.yml: 5 jobs (gitleaks, trivy, gosec, dependency-review, CodeQL)
- release.yml: full pipeline with feature-flag guards for AI changelog,
  macOS notarization, AUR, Homebrew, skills sync, and PGO
- ai-labeler.yml: AI-powered PR classification and breaking change detection
- dependabot-auto-merge.yml: auto-merge minor/patch updates
- labeler.yml: path-based PR labeling

All optional features degrade gracefully with zero secrets configured.
GitHub config: dependabot, CODEOWNERS, PR template, release categories,
labeler rules, CodeQL config. AI prompts for PR classification, breaking
change detection, and changelog generation. Local dev: pre-commit hooks,
gitleaks config, and release documentation templates.
Add all new seed files to the copy-and-customize section, fix skills
template path (seed/skills/SKILL.md.tmpl -> seed/skills/app/SKILL.md.tmpl),
add GitHub infra setup and secrets configuration documentation.
Copilot AI review requested due to automatic review settings March 5, 2026 01:52

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a complete release-engineering stack for both this repo and the seed CLI templates, covering CI/security/release automation, local developer tooling, and documentation needed to bootstrap new CLIs with the same infra from day one.

Changes:

  • Add/expand GitHub Actions workflows for tests, security scans, releases, labeling, and Dependabot automation.
  • Add release/security tooling (Make targets, release + skills sync scripts, PGO profiling and CLI surface snapshot/diff utilities).
  • Add templates/docs for RELEASING, pre-commit, gitleaks, and seed bootstrap instructions.

Reviewed changes

Copilot reviewed 39 out of 39 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
seed/scripts/sync-skills.sh Fix quoting when iterating skills directories in seed script.
seed/scripts/release.sh.tmpl Add seed release script template (tagging + preflight).
seed/scripts/collect-profile.sh Add seed PGO profile collection script.
seed/scripts/check-cli-surface.sh Add seed CLI surface snapshot generator.
seed/scripts/check-cli-surface-diff.sh Add seed CLI surface diff gate (fail on removals).
seed/RELEASING.md.tmpl Add seed release process + feature toggle matrix docs.
seed/Makefile Add seed releng targets (tidy/security/release/surface/PGO/skills).
seed/.pre-commit-config.yaml.tmpl Add seed pre-commit configuration template.
seed/.gitleaks.toml.tmpl Add seed gitleaks configuration template.
seed/.github/workflows/test.yml Add seed CI workflow (tests/lint/security/race/integration/surface/benchmarks).
seed/.github/workflows/security.yml Add seed security workflow (gitleaks/trivy/gosec/codeql/dependency-review).
seed/.github/workflows/release.yml Add seed release workflow (security + quality gate + GoReleaser + optional extras).
seed/.github/workflows/labeler.yml Add seed labeler workflow (actions/labeler).
seed/.github/workflows/dependabot-auto-merge.yml Add seed Dependabot auto-merge workflow (guarded).
seed/.github/workflows/ai-labeler.yml Add seed AI PR classification + breaking-change labeling workflow.
seed/.github/release.yml Add seed GitHub Releases changelog category config.
seed/.github/pull_request_template.md Add seed PR template.
seed/.github/prompts/summarize-changelog.prompt.yml Add seed AI prompt for release summary prose.
seed/.github/prompts/detect-breaking.prompt.yml Add seed AI prompt for breaking-change detection.
seed/.github/prompts/classify-pr.prompt.yml Add seed AI prompt for PR categorization labels.
seed/.github/labeler.yml.tmpl Add seed labeler rules template.
seed/.github/dependabot.yml Add seed Dependabot configuration template.
seed/.github/codeql/codeql-config.yml Add seed CodeQL configuration.
seed/.github/CODEOWNERS.tmpl Add seed CODEOWNERS template.
scripts/sync-skills.sh Add repo skills distribution sync script (CI release hook).
scripts/release.sh Add repo (library) release script (tagging + preflight).
prompts/seed-cli.md Update bootstrap instructions to include new releng files and setup steps.
RELEASING.md Add repo (library) releasing documentation.
Makefile Add repo releng targets (tidy/security/release-check/release).
.pre-commit-config.yaml Add repo pre-commit hooks configuration.
.mise.toml Pin Go toolchain via mise.
.github/workflows/test.yml Add repo CI workflow (test/lint/govulncheck/race).
.github/workflows/security.yml Add repo security workflow (gitleaks/trivy/gosec/codeql/dependency-review).
.github/workflows/release.yml Add repo release workflow (security + test gate + module publish + optional skills sync).
.github/workflows/dependabot-auto-merge.yml Add repo Dependabot auto-merge workflow.
.github/release.yml Update repo changelog exclusions (labels/authors).
.github/dependabot.yml Expand repo Dependabot configuration (scheduling/groups/cooldowns).
.github/codeql/codeql-config.yml Add repo CodeQL configuration.
.github/CODEOWNERS Update repo code ownership rules.
Comments suppressed due to low confidence (3)

seed/.github/workflows/release.yml:317

  • The docs/template matrix says skills sync is gated by a guard combo (App ID + private key), but the job-level if: only checks vars.SKILLS_APP_ID. If the var is set but secrets.SKILLS_APP_PRIVATE_KEY is missing, actions/create-github-app-token will fail and the job will error (even if continue-on-error hides it). Align the guard with the documented combo by adding a non-secret-derived env flag (e.g., HAS_SKILLS_KEY) and checking that, or by adding an explicit preflight step that sets an output-and-guards subsequent steps.
    if: >-
      startsWith(github.ref, 'refs/tags/v') &&
      vars.SKILLS_APP_ID != ''

scripts/sync-skills.sh:65

  • This copy loop will mis-handle filenames containing spaces/newlines because it relies on newline-delimited output piped into read -r f. Also, ! -name '.*' won’t reliably exclude files under hidden directories like ./.foo/bar.txt. Use find ... -print0 with while IFS= read -r -d '' f and exclude hidden paths via a -path '*/.*' -prune (or equivalent) to make the sync deterministic and safe.
  # Copy non-Go, non-dotfiles preserving subdirectory structure
  (cd "$skill_dir" && find . -type f ! -name '*.go' ! -name '.*' | while read -r f; do
    mkdir -p "$dest/$(dirname "$f")"
    cp "$f" "$dest/$f"
  done)

seed/scripts/collect-profile.sh:1

  • With set -e, this will exit the script if ./internal/... doesn’t exist or has no packages (common in early-stage repos or repos without internal/). If this is intended as a general-purpose seed utility, consider falling back to go list ./..., or detect absence of internal/ and emit a clear message / skip profile generation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread seed/.github/workflows/release.yml Outdated
Comment thread seed/.github/workflows/release.yml Outdated
Comment thread .github/workflows/dependabot-auto-merge.yml Outdated
All 37signals CLIs are on Go 1.26 now.
…om auto-merge

- seed release.yml: replace `ls bin/` with `find bin/ -print -quit` for
  deterministic single-binary selection
- dependabot-auto-merge.yml: exclude github_actions ecosystem from
  auto-merge to maintain review barrier on CI-critical code
Copilot AI review requested due to automatic review settings March 5, 2026 01:58

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ebada31b06

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread seed/Makefile
jeremy added 2 commits March 4, 2026 18:05
Add .golangci.yml (v2 format) matching the seed template linter set.
Fix all unchecked return values: cleanup calls in error paths use
explicit _ discard, test assertions use require.NoError.
When DRY_RUN=local, create a stub git repo instead of cloning the
remote skills repo. This lets contributors run make sync-skills
without needing access credentials.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 46 out of 46 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (5)

seed/Makefile:22

  • check is meant to be the fast inner-loop target (fmt-check + vet + test (+ test-e2e for CLIs) per MAKEFILE-CONVENTION.md). Adding tidy-check here makes check slower and introduces a git-diff dependency; consider moving tidy-check to check-all / CI-only gates instead.
    .github/workflows/security.yml:33
  • Installing gitleaks via curl ... | tar -xz without checksum/signature verification weakens the supply-chain guarantees of this security workflow. Prefer using a pinned action for gitleaks, or download the release artifact and verify its checksum/signature before executing it.
      - name: Install gitleaks
        run: |
          curl -sSfL https://github.com/gitleaks/gitleaks/releases/download/v8.21.2/gitleaks_8.21.2_linux_x64.tar.gz | tar -xz
          sudo mv gitleaks /usr/local/bin/

seed/.github/workflows/security.yml:32

  • Installing gitleaks via curl ... | tar -xz without checksum/signature verification weakens the supply-chain guarantees of this security workflow. Prefer using a pinned gitleaks action, or verify the downloaded artifact’s checksum/signature before moving it into PATH.
    scripts/sync-skills.sh:65
  • This sync logic only copies files into the destination directory; if a file is deleted or renamed in the source skill, the old file will remain in the destination skill directory and keep getting published. Consider wiping the destination skill directory (or deleting files not present in the source) before copying so the target repo is an exact mirror of the current skill contents.
  echo "No skills found in ${SKILLS_DIR}/"
  exit 0
fi

echo "Found ${#SKILL_DIRS[@]} skill(s) to sync"

# Copy skills to target repo
MANAGED_SKILLS=()

seed/scripts/collect-profile.sh:2

  • For portability/consistency with the other scripts in this template (which use #!/usr/bin/env bash), consider switching this shebang from #!/bin/bash to #!/usr/bin/env bash so it works in environments where bash isn’t located at /bin/bash.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/release.sh
Comment thread Makefile
Comment thread seed/Makefile
jeremy added 2 commits March 4, 2026 18:10
- Nest settings under linters.settings (not top-level linters-settings)
- Move gofmt to formatters.enable (formatter, not linter in v2)
- Remove gosimple (merged into staticcheck in v2)
- Remove exclude-use-default (removed in v2)
- Set errcheck check-blank: false (true flags explicit _ = discards)
- Add version: "2" to seed config
trivy-action 0.34.1 auto-resolves to latest Trivy which currently
fails to download. Pin a known-good version.
Copilot AI review requested due to automatic review settings March 5, 2026 02:12
@github-advanced-security

Copy link
Copy Markdown

This pull request sets up GitHub code scanning for this repository. Once the scans have completed and the checks have passed, the analysis results for this pull request branch will appear on this overview. Once you merge this pull request, the 'Security' tab will show more code scanning analysis results (for example, for the default branch). Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results. For more information about GitHub code scanning, check out the documentation.

- Add replace-check target to library Makefile (guards against replace
  directives in go.mod before release)
- Include replace-check in release-check prerequisite chain
- Add .DEFAULT_GOAL := check to both Makefiles so bare `make` runs the
  check target regardless of .PHONY ordering

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 47 out of 47 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (4)

seed/Makefile:162

  • vuln runs govulncheck but doesn’t verify it’s installed. Since release-check depends on vuln, missing tooling will fail with an unhelpful “command not found”. Add a presence check with a clear install hint (or install govulncheck inside the target).
    seed/scripts/collect-profile.sh:44
  • The PGO profiling go test -bench=. invocation will still run package tests unless -run is set. That can significantly increase runtime and skew the profile away from benchmarks. Add -run=^$ (or similar) so only benchmarks execute when collecting profiles.
    seed/.github/workflows/release.yml:164
  • This PGO collection step runs go test -bench=. without -run, so it will execute unit tests in addition to benchmarks. That can make releases slower and produce profiles dominated by test setup rather than benchmark hot paths. Add -run=^$ (or equivalent) to restrict execution to benchmarks for profiling.
    Makefile:54
  • vuln assumes govulncheck is already installed, but release-check depends on it, so a fresh dev machine will fail with a generic “command not found”. Mirror the secrets target pattern by checking for govulncheck and printing an explicit install instruction (or install it in the target).
# Guard against local replace directives in go.mod
replace-check:
	@if grep -q '^[[:space:]]*replace[[:space:]]' go.mod; then \
		echo "ERROR: go.mod contains replace directives"; \
		grep '^[[:space:]]*replace[[:space:]]' go.mod; \

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/sync-skills.sh Outdated
Comment thread seed/scripts/sync-skills.sh
Use a temp gitconfig file with GIT_CONFIG_GLOBAL instead of embedding
the token directly in the clone URL or passing it via git -c. The
token is written to a temp file (cleaned up on exit) and never appears
in process listings.
@jeremy
jeremy merged commit bf4c173 into main Mar 5, 2026
13 checks passed
@jeremy
jeremy deleted the releng branch March 5, 2026 02:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants