Skip to content

ci: automate SemVer releases with semantic-release - #7

Merged
jvcorredor merged 2 commits into
mainfrom
discord-6-ci-semantic-release
Sep 12, 2026
Merged

jvcorredor merged 2 commits into
mainfrom
discord-6-ci-semantic-release

Conversation

@jvcorredor

@jvcorredor jvcorredor commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds the repository's first .github/workflows/ and automates SemVer releases from Conventional Commits:

  • .releaserc.json — explicit commit-analyzer, release-notes-generator, and github plugin list. Required because semantic-release otherwise loads @semantic-release/npm and fails without a package.json; the repo stays a pure Go module. parserOpts.breakingHeaderPattern makes the ! shorthand register as breaking, and a releaseRules entry keeps revert commits non-releasing.
  • .github/workflows/release.yml — on push to main, runs semantic-release@25 on Node 22 (fetch-depth: 0, persist-credentials: false, concurrency: release) and cuts vX.Y.Z tags + GitHub Releases with generated notes.
  • .github/workflows/lint.yml — commitlint on pull-request commits (pull_request; falls back to @commitlint/config-conventional) and Conventional Commit PR titles (pull_request_target; uses the action's conventional-commit-types defaults).

Closes: #6

Verification

  • actionlint passes on both workflows; .releaserc.json and both YAML files parse.
  • Local semantic-release@25 --dry-run --no-ci against a scratch clone seeded with v0.1.0:
    • fix:0.1.1
    • feat:0.2.0
    • feat!:, fix!:, feat(scope)!:, and a BREAKING CHANGE: footer → 1.0.0
    • revert: / git-style Revert "…" / docs: / ci: / refactor: / chore: → no release
  • Bootstrap seed v0.1.0 GitHub Release created at the current main HEAD (64db650), so the first automated release is v0.1.x, not v1.0.0.

Notes

  • pull_request_target workflows are loaded from the default branch, so the PR-title check activates only after this merges; commitlint runs on this PR now.
  • Requiring the lint checks via ruleset/branch protection is a settings change and stays out of this PR.
  • No CHANGELOG.md is committed (GitHub Releases carry the notes), per the ticket.

Add semantic-release config and a release workflow that cuts vX.Y.Z
tags and GitHub Releases from Conventional Commits on main, plus
PR linting for commit messages and PR titles.

Refs: #6

@jvcorredor jvcorredor left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Spec-compliance review — PR #7 vs issue #6

Verdict: faithful, working implementation. One behavioral spec deviation (medium) and one PR-description inaccuracy (low). Not blocking; the deviation is a small .releaserc.json change or an amendment to issue #6.

Verified

  • .releaserc.json matches the Design snippet exactly and parses.
  • release.yml matches the design line-for-line: trigger, permissions, concurrency: release with cancel-in-progress: false, fetch-depth: 0, persist-credentials: false, Node 22, npm install --no-save semantic-release@25, npx semantic-release with GITHUB_TOKEN. Stripping credentials does not break tag push: semantic-release 25.0.9 rebuilds an authenticated x-access-token: URL from GITHUB_TOKEN when GITHUB_ACTION is set (lib/get-git-auth-url.js).
  • lint.yml matches the design. wagoid v6 defaults to commitlint.config.mjs and falls back to @commitlint/config-conventional when absent. Confirmed live on this PR: Commit messages ran and passed (run 34707461590, job 103589998107); PR title correctly skips until the workflow exists on main.
  • actionlint .github/workflows/release.yml .github/workflows/lint.yml → exit 0, no findings.
  • Bootstrap: v0.1.0 is a published release whose tag points at 64db650 = current main HEAD; PR head is the single ci: commit. Independently reproduced with semantic-release 25.0.9 against the real seed tag: ci: → no release, fix:0.1.1 with generated notes, refactor: → no release.
  • Out-of-scope check: the diff adds only the three in-scope files — no CHANGELOG.md, no go test/go vet ci.yml, no GoReleaser, no npm/Docker publishing.

Findings

  1. Medium — .releaserc.json:4: revert commits cut a patch release, contradicting issue #6's no-release mapping. Inline comment.
  2. Low — .github/workflows/lint.yml:29: PR body overstates the fallback behavior of the PR-title action. Inline comment.

Could not verify pre-merge

  • End-to-end tag + Release creation on a push to main (first possible only after this merges; dry-run covers commit analysis and note generation).
  • A non-conventional PR title actually failing: pull_request_target loads the workflow from the default branch, so it activates after merge (acknowledged in the PR body). The commitlint failure path is likewise covered by the action docs, not exercised here.
  • Making the lint checks required merge gates — explicitly a settings/ruleset task, out of scope.

Comment thread .releaserc.json Outdated
Comment thread .github/workflows/lint.yml

@jvcorredor jvcorredor left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Verdict: no functional defects found — approve with hardening nits. I could not break the release path.

What I verified (sources + live experiment):

  • actionlint is clean on both workflows.
  • I ran real semantic-release@25 --dry-run against scratch repos with a file:// remote using this exact .releaserc.json and seed tag: v0.1.0 + fix -> 0.1.1; perf -> 0.1.1; ci/docs/chore/refactor/style/revert: and merge commits -> no release; no tag with historical feat -> 1.0.0. A note-less, API-created lightweight seed tag is recognised (lib/branches/get-tags.js defaults it to channel [null]).
  • persist-credentials: false is correct: core pushes the tag itself, but lib/get-git-auth-url.js rewrites the remote to x-access-token:$GITHUB_TOKEN because GITHUB_ACTION is set. fetch-depth: 0 is required and present.
  • No package.json is needed: npm install --no-save semantic-release@25 in an empty dir installed 301 packages, left no package.json/package-lock.json, and npx found the local binary. Node 22 satisfies ^22.14.0 || >=24.10.0.
  • commitlint gets the right commits: wagoid v6 uses pulls.listCommits (API), not local history, so the checkout depth is irrelevant. config-conventional v19 includes ci/build; amannn v6 defaults to conventional-commit-types, which includes ci. This PR's own ci: merge passes both and cuts no release.
  • pull_request_target here is the safe variant: read-only permissions, no PR checkout, no PR code execution. Skipped sibling jobs report skipped, which does not block required checks.

Residual risks / process notes (not blockers): the v0.1.0 seed is a manual prerequisite the workflow cannot enforce — if this merges before the tag is seeded, the first run analyses all history and ships 1.0.0; a failed run between the tag push and release creation leaves a tag with no release (retry computes the next version, so manual tag cleanup is needed); and with no lockfile each push installs a floating dependency tree. Line comments cover the actionable hardening.

Comment thread .github/workflows/lint.yml
Comment thread .github/workflows/lint.yml
Comment thread .github/workflows/lint.yml
Comment thread .github/workflows/release.yml
Teach the parser the `!` breaking-change shorthand and pin revert
commits to no release, so feat!/fix!/BREAKING CHANGE map to major
and revert stays inert, matching the mapping in #6.

Refs: #6
@jvcorredor
jvcorredor merged commit d0e91ee into main Sep 12, 2026
2 checks passed
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 0.1.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@jvcorredor
jvcorredor deleted the discord-6-ci-semantic-release branch September 12, 2026 17:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ci: automate SemVer releases with semantic-release and Conventional Commits

1 participant