Skip to content

chore: prepare 0.2.0 release - #248

Merged
santosr2 merged 26 commits into
mainfrom
chore/prep-0.2.0-release
Jul 21, 2026
Merged

chore: prepare 0.2.0 release#248
santosr2 merged 26 commits into
mainfrom
chore/prep-0.2.0-release

Conversation

@santosr2

Copy link
Copy Markdown
Owner

What and why

Prepares the 0.2.0 stable release: release-tooling fixes, CI/Action correctness fixes, several genuine bug fixes, and documentation accuracy passes. Unblocks mise run bump:stable and cleans up the release pipeline so a signed v0.2.0 tag cuts cleanly.

Release tooling

  • Keep output-formats.md version strings tracking current_version so bump-my-version no longer aborts (this was blocking every mise run bump:*).
  • Replace bump:release with bump:stage/bump:stable.
  • Drop stale CHANGELOG.md from release archives (it is regenerated post-tag by the update-changelog job, so the bundled copy was always one version behind).
  • Publish multi-arch amd64/arm64 Docker images.
  • Publish the VS Code extension from the release workflow, document the stable-only Marketplace policy, and correct the Marketplace link in release notes.

Action / CI

  • Upload SARIF even when findings fail the run (add always() to the upload step) so results still reach the Security tab when fail-on-error trips.
  • Fail on tool errors and honor parallel: false.
  • Float Go to 1.26.x, and smoke-test the published Homebrew formula rather than the tag's checkout.

Bug fixes

  • Import pkg/plugins (not internal/plugins) in the plugins init scaffold and the authoring guide, so plugins scaffolded by external users actually compile.
  • Fail on unset ${VAR:?} required environment variables in config.
  • Use a relative display path for the JUnit testsuite name.

Docs

  • Correct the data_files format (JSON only, not YAML), the format engine package name (format/, not fmt/), release-facing inaccuracies, custom-rule testing steps, stale Go/OPA versions, and the default-mode quickstart output.
  • Adopt Contributor Covenant 3.0 and drop @latest deprecation notices.

VS Code

  • Bump the extension to 0.2.1, pin Bun to 1.2.x, and pin moduleResolution for TypeScript 7.

Why: get the repo release-ready so a v0.2.0 tag exercises a correct pipeline end to end (bump, changelog, multi-arch Docker, Homebrew, Marketplace, SARIF) against accurate docs.

How to test

  • mise run check (fmt + vet + lint + unit tests) — green.
  • mise run test:integration — green.
  • ./bin/terratidy check examples/ — exit 0.
  • bump-my-version bump --new-version 0.2.0 --dry-run --allow-dirty — exits 0 (previously aborted with "Did not find ...").
  • goreleaser check — validates (only the already-known dockers/brews deprecation notices).
  • mise run docs:build (mkdocs --strict) — builds clean.
  • Plugin scaffold: terratidy plugins init myplugin, then go build -buildmode=plugin against the module in an external checkout — compiles (previously failed with "use of internal package not allowed").

Notes for reviewers

  • Post-tag manual steps (not automated here): merge to main, mise run bump:stable, then a signed git tag -s v0.2.0.
  • The release environment requires manual reviewer approval, so the goreleaser/vscode-publish jobs will pause (not hang) after the tag is pushed.
  • The floating v0 alias tag has never actually been created (only v0.1.0 predates the update-version-tags job), so confirm it lands on origin right after tagging.
  • Non-blocking follow-ups from the release-readiness audit (Dockerfile OCI labels, dead-code -X main.version ldflags, a few doc-accuracy nits, Action self-test coverage gaps) are tracked internally for post-release.
  • No internal/buildinfo/version.json change is included; that file is expected build-placeholder noise and must land empty.

Checklist

  • I have read the CONTRIBUTING guidelines
  • My code follows the project's code style
  • I have added tests that prove my fix/feature works
  • All checks pass (mise run check runs fmt, vet, lint, and test)
  • I have updated documentation as needed
  • My commits follow Conventional Commits

🤖 Generated with Claude Code

santosr2 and others added 26 commits July 21, 2026 14:19
The ${VAR:?error} syntax was documented as failing when the variable is
unset, but expandEnvVars silently substituted an empty string and left a
comment claiming validation would catch it. It never did, so a config
declaring a required policy path or data file quietly loaded with that
value blanked out.

expandEnvVars now returns an error listing every unset required variable
(not just the first), and both call sites propagate it with the config
path. Update the docs example to use real config keys and document the
one-shot reporting behavior.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The upgrade guide, SDK docs, and a FixResult godoc note all attributed
five breaking changes to v0.2.0-alpha.5, a version that was never tagged.
The alpha.4 -> 0.2.0 jump means these changes first ship publicly in
0.2.0, so relabel every reference accordingly and rewrite the three
anchor links the heading renames would otherwise break. Also reword the
intermediate-signature note that the relabel made self-contradictory.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The publish job lived in vscode.yml behind a combined tags + paths push
filter, so a tag push never satisfied the path filter and the job had
never once fired. Move publishing into release.yml as a vscode-publish
job that needs goreleaser, guaranteeing the GitHub release exists before
the .vsix upload (removing the race and its wait loop). Every tag now
attaches the .vsix to the release; only stable tags publish to the
Marketplace. vscode.yml returns to CI-only with its original path filter.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…pt 7

Extension 0.2.0 is already published to the Marketplace, so the v0.2.0
release needs a fresh version. Bump to 0.2.1 and update the version
scheme comment for the new policy: only stable releases publish to the
Marketplace, pre-releases attach the .vsix to the GitHub release, so the
CLI and extension versions realign from 0.3.0 onward.

Also set moduleResolution explicitly to "bundler". TypeScript 7 removed
the implicit node10 default, and bundler is the only value compatible
with module: commonjs, matching the esbuild-bundled publish path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
bump:release ran `bump-my-version bump pre_l`, which advances one step
through the pre-release ladder (alpha -> beta -> rc -> final). From alpha
that lands on 0.2.0-beta, not a stable version, contradicting the task's
own description. Split into two honestly-named tasks: bump:stage advances
one pre-release step, and bump:stable drops the suffix outright by
bumping to the base version, so a release can be cut directly from a
pre-release.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
With v0.2.0 shipping as the first stable tag since v0.1.0, @latest
resolves correctly again, so remove the temporary "avoid @latest /
broken module path" warnings from the README and installation guide and
keep pinned versions as the documented default. Mark 0.1.x unsupported
in SECURITY.md. Add the missing bump-my-version entry so the
installation guide's go-install pin actually gets bumped instead of
being stuck at alpha.4 forever. Also fix the README clone command
(cd TerraTidy) and sync CLAUDE.md with the bump-task rename, the VS Code
publish workflow move, the 9-setting count, and the non-symlink icon.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the 2.1-derived code of conduct (which claimed 2.1 lineage while
omitting its enforcement ladder and named no reporting channel) with the
verbatim Contributor Covenant 3.0. Fill both official placeholders: the
private reporting channel points at the GitHub advisory form (the only
genuinely private route), with a GitHub Support escalation path for
reports concerning the sole maintainer.

Fix the contributor guide: the fork clone command pointed at upstream,
and the commit-type list omitted the vscode and container prefixes that
CI enforces on PR titles.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Update the extension versioning docs to match the new distribution
model: only stable releases publish to the Marketplace, pre-releases
attach a .vsix to the GitHub release. Correct the version-mapping table
(0.2.0 CLI maps to extension 0.2.1, realigning from 0.3.0) and replace
the now-invalid "Install Pre-Release Version" Marketplace instructions
with .vsix install steps.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
CONTRIBUTING.md documented `test-rule my-rule` for Go rules, but
test-rule requires a .rego file path and only dispatches the policy
engine; Go rules are validated with `go test`. Split the snippet into
correct Go and Rego workflows.

upgrade.md claimed Go 1.26.4+ (go.mod requires 1.25.0, CI tests 1.25.x)
and OPA v1.15.0 (go.mod pins v1.18.2). Corrected the Go floor and
switched the OPA references to unversioned "v1.x" so they stop drifting
on every dependency bump.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Rubens <rubenssegundo404@gmail.com>
run-action.sh derived the fail decision only from parsed finding counts.
On `format: json`, a config (exit 2) or internal (exit 3) error writes
no JSON summary, so the counts fell back to 0 and the step reported
success even with fail-on-error: true. Fail the step outright on any
exit code >= 2.

`parallel: false` was a no-op: only --parallel was ever passed, so the
config default (parallel: true) always won. Emit --no-parallel when the
input is false.

The build-from-source guard grepped for the module path anywhere in
go.mod, which matches every SDK consumer and made the action try to
build the consumer's own module. Match the module declaration line.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Rubens <rubenssegundo404@gmail.com>
The dockers config built a single (amd64) image, so arm64 pulls fell
back to emulation. Split into per-arch builds that push tag-suffixed
images (:<tag>-amd64, :<tag>-arm64) and merge them with docker_manifests
into the real tags: :<tag> for every release, and :latest / :vX / :vX.Y
for stable releases only (gated on prerelease via skip_push).

Add QEMU and buildx setup to the release job to drive the arm64 build.
This also removes the duplicate-image-registration warning the former
two-entry dockers config produced.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Rubens <rubenssegundo404@gmail.com>
.github/DISCUSSION_TEMPLATE/q-a.yml had a hardcoded version placeholder
with no bump-my-version entry, so it never advanced past its original
value. Add a file entry so it tracks on every version bump like the
bug-report template does.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Rubens <rubenssegundo404@gmail.com>
Parallel execution is the config default, so a fresh `terratidy check`
shows the compact output, not the numbered per-engine block. Swap the
two examples so the default is shown first, move the numbered output
under --no-parallel, and add the missing --no-parallel row to the
check-command flags table.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The release-notes header linked itemName=santosr2.terratidy; the
published extension id is santosr2.vscode-terratidy.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
GoReleaser pushes the generated formula to main after the tag is cut,
so test-homebrew must check out main to exercise the real formula
instead of the stale one on the tag commit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Matches the floating pin every other workflow uses and stops the
hardcoded patch drifting behind mise.toml.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
`cd terratidy` fails on case-sensitive filesystems; the cloned dir is
TerraTidy.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The JUnit formatter set each <testsuite name> to the raw finding path
(absolute), while classname and every other formatter use the relative
DisplayPath. Real runs therefore emitted an absolute suite name that
was inconsistent with the rest of the output. Use DisplayPath so the
suite name matches classname and honors --absolute-paths.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The JSON, SARIF, JUnit, and Markdown examples no longer matched actual
output: JSON showed a nonexistent top-level version/timestamp and flat
line/column instead of the nested location object; SARIF used the wrong
$schema URL; JUnit grouped suites by engine rather than by file; and
Markdown used an outdated section layout. Regenerate every example from
real `terratidy check --format <fmt>` runs, and document the format
aliases (gha, junit-xml, md) and the severity icons.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- action.yml: note that the parallel input defaults to false (unlike
  the CLI) for deterministic CI ordering
- github-actions.md: exit 1 means an error-level finding exists, not
  findings of any severity
- quickstart.md: show the literal `terratidy init` output
- README: link the upgrade guide and normalize badge slugs to the
  TerraTidy casing (Codecov is case-sensitive)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The float-pinned bun (1) resolved to a newer major locally than CI's
1.2.x, and the committed lockfile predated bun's configVersion field,
so every local `bun install` rewrote bun.lock. Pin mise to 1.2 to
match CI and commit the current-format lockfile to stop the churn.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rsion

A prior regenerate-from-CLI commit stripped the pre-release suffix from the
SARIF driver version and added an untracked "Generated by" footer, so
bump-my-version aborted ("Did not find ...") and blocked every mise run
bump:* task. Restore both strings to the current version and add a bump
entry for the footer so it tracks going forward.
The upload-sarif step lacked always(), so when error findings tripped the
default fail-on-error the composite action skipped the upload and findings
never reached the Security tab, exactly the case that matters. Gate the step
on always() so it also runs on the failing path.
terratidy plugins init and the plugin authoring guide imported
internal/plugins, which modules outside this repo cannot import ("use of
internal package not allowed"), so scaffolded plugins failed to compile.
Switch both to the public pkg/plugins, which re-exports an identical API,
matching the working examples/go-rule.
The update-changelog job runs after GoReleaser packages, so every release
archive bundled a CHANGELOG.md missing its own version's entry. The GitHub
release body already links the live changelog on main, so remove the bundled
copy rather than ship a stale one.
configuration.md claimed policy data_files accepts JSON or YAML, but the
loader only parses JSON (a YAML file crashes with exit 3). architecture.md's
directory tree named the format engine package fmt/ instead of format/.
@codecov

codecov Bot commented Jul 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.66667% with 6 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/config/config.go 62.50% 3 Missing and 3 partials ⚠️

📢 Thoughts on this report? Let us know!

@santosr2
santosr2 merged commit 7ba5992 into main Jul 21, 2026
55 of 56 checks passed
@santosr2
santosr2 deleted the chore/prep-0.2.0-release branch July 21, 2026 23:55
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.

1 participant