Commit Graph

33 Commits

Author SHA1 Message Date
k3nny 3fd8dc2a49 build: add install task command that copies the build binary into /usr/local/bin
ci / vet, staticcheck, test, build (push) Successful in 3m27s
2026-07-12 14:30:52 +02:00
k3nny d790a9edfe feat(notify): release v1.8.0 — Slack/Teams/Google Chat/Telegram/webhook notifications
ci / vet, staticcheck, test, build (push) Successful in 4m10s
docs / Build and deploy docs (push) Failing after 10s
release / Build and publish release (push) Successful in 5m9s
- Add internal/notify package: best-effort release notifications to Slack, Microsoft Teams, Google Chat, Telegram, and a generic JSON webhook; every target is independently opt-in and a failed notification never fails the release
- Add notify config section (slack_webhook_url, teams_webhook_url, google_chat_webhook_url, telegram_bot_token/telegram_chat_id, webhook_url) with matching env var fallbacks; 100% coverage plus FuzzMessagePayloads
- Wire notification sending into run() — fires after tag+push (including --no-release), skipped on --no-push/--no-commit since nothing was published yet
- Document the notify section in README, Hugo docs, and .releaser.yml template; update CLAUDE.md architecture/fuzzing tables
- Also commit the Apache License 2.0 docs-site footer link (docs/hugo.toml geekdocContentLicense), left uncommitted from a prior change

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v1.8.0
2026-07-12 13:55:57 +02:00
k3nny 51343768d9 chore(releaser): release v1.7.1 — Apache 2.0 license, Hugo build fix
ci / vet, staticcheck, test, build (push) Successful in 3m53s
- Add Apache License 2.0 (Copyright 2026 K3nnyfr <alex@k3nny.fr>), linked from a new README License section
- Fix task docs:build leaving stale files in docs/public by passing --cleanDestinationDir to hugo
- Ignore /.task/ (Task runner's local checksum cache)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-12 13:18:53 +02:00
k3nny a14c3f1181 feat(pyproject): release v1.7.0 — Python pyproject.toml version bump
ci / vet, staticcheck, test, build (push) Successful in 3m2s
docs / Build and deploy docs (push) Failing after 13s
release / Build and publish release (push) Successful in 4m29s
Add internal/pyproject package with ReadVersion and WriteVersion for
pyproject.toml files. Reads [project].version (PEP 621) first, then
falls back to [tool.poetry].version. Section boundaries are detected
via TOML's rule that headers always start at the beginning of a line
(\n[ pattern), so inline arrays with [ characters don't interfere.

Config follows the established multi-value pattern:
- python.pyproject_toml: single path (opt-in, no default)
- python.pyproject_tomls: list for monorepos (overrides single)
- --pyproject flag overrides pyproject_toml and clears pyproject_tomls

100% per-package statement coverage maintained across all 14 packages;
FuzzReadVersion and FuzzWriteVersion added per fuzzing guidelines.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v1.7.0
2026-07-12 00:22:49 +02:00
k3nny 7483fd4194 docs(roadmap): add Python pyproject.toml version bump to backlog
ci / vet, staticcheck, test, build (push) Successful in 3m13s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-12 00:13:51 +02:00
k3nny c1ecd947ac docs(releaser): fix Geekdoc edit path — content/ was duplicated
ci / vet, staticcheck, test, build (push) Successful in 3m3s
docs / Build and deploy docs (push) Failing after 17s
Geekdoc sets geekdocFilePath to the file path relative to the Hugo
working dir (docs/), so it already begins with content/. The previous
value "docs/content" caused the join to produce docs/content/content/.
Corrected to "_edit/main/docs".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-12 00:01:29 +02:00
k3nny 712abe3c9d docs(releaser): fix Geekdoc edit link for Gitea
ci / vet, staticcheck, test, build (push) Successful in 3m37s
docs / Build and deploy docs (push) Failing after 15s
Gitea uses /_edit/ instead of /edit/ in its file editor URLs. Change
geekdocEditPath from "edit/main/docs/content" to "_edit/main/docs/content"
so the "Edit this page" links resolve correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 23:59:32 +02:00
k3nny d053faeb23 docs(releaser): fix repo URLs and add repository link
ci / vet, staticcheck, test, build (push) Successful in 4m34s
docs / Build and deploy docs (push) Failing after 12s
All git.k3nny.fr/releaser links were missing the /k3nny/ namespace.
Fixed in docs/hugo.toml (geekdocRepo + geekdocEditPath), installation,
ci-integration, and changelog pages. Also added repo link to the docs
home page and README.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 23:57:02 +02:00
k3nny 8a5aae3de9 docs(releaser): release v1.6.3 — logo, baseURL, gitignore fix
ci / vet, staticcheck, test, build (push) Successful in 3m32s
- Add releaser-logo-1024.png as Geekdoc site header logo (geekdocLogo)
  and a 128×128 resized copy in README
- Set docs/hugo.toml baseURL to https://releaser.k3nny.fr/
- Anchor .gitignore binary pattern to /releaser-* to stop it matching
  files inside docs/static/images/
- Restore docs URL link in README lost during merge to main

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 23:37:17 +02:00
k3nny 4f0592e342 docs(releaser): add logo to documentation site and README
ci / vet, staticcheck, test, build (push) Successful in 3m11s
docs / Build and deploy docs (push) Failing after 15s
- docs/hugo.toml: set geekdocLogo to images/releaser-logo-1024.png so
  Geekdoc renders it in the site header
- docs/static/images/releaser-logo-128.png: 128×128 version resized from
  the 1024×1024 source via ImageMagick for README display
- README.md: add logo above the release badge
- .gitignore: scope releaser-* to repo root (/releaser-*) so it no
  longer matches files inside docs/static/images/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 23:31:23 +02:00
k3nny 232a0eb903 docs(releaser): restore docs URL lost in merge to main
ci / vet, staticcheck, test, build (push) Failing after 10s
docs / Build and deploy docs (push) Failing after 17s
Re-apply two changes that were dropped when release/1.0 was merged into
main via Gitea:
- README.md: Documentation link to https://releaser.k3nny.fr
- docs/hugo.toml: baseURL set to https://releaser.k3nny.fr/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 22:59:28 +02:00
k3nny e3b47d0585 Merge pull request 'Release/1.0' (#1) from release/1.0 into main
ci / vet, staticcheck, test, build (push) Successful in 3m30s
docs / Build and deploy docs (push) Failing after 29s
Reviewed-on: #1
2026-07-11 22:11:19 +02:00
k3nny 88ed87b095 build(ci): release v1.6.2 — staticcheck in task ci, SA4006 fix
ci / vet, staticcheck, test, build (push) Successful in 3m5s
ci / vet, staticcheck, test, build (pull_request) Failing after 12s
Add go tool staticcheck ./... to the task ci pipeline (between vet and
test), consistent with the Gitea CI workflow. Fix the SA4006 it surfaced
in TestLatestTagTagsIterFails where err from PlainOpen was assigned but
never read before being overwritten.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 21:47:39 +02:00
k3nny 6381a6440b build(ci): add staticcheck to CI pipeline; fix SA4006 in gitutil test
ci / vet, staticcheck, test, build (push) Successful in 3m5s
Add `go tool staticcheck ./...` between vet and test in the `task ci`
pipeline. Fix the SA4006 finding it surfaced: the PlainOpen error in
TestLatestTagTagsIterFails was assigned but never read (the nil check was
lost when the skip logic was simplified).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 21:45:49 +02:00
k3nny 4f933bf130 fix(ci): release v1.6.1 — skip chmod tests when running as root
ci / vet, staticcheck, test, build (push) Failing after 3m0s
Four tests relied on os.Chmod to force error paths but were failing in
Docker CI (golang:1.26-alpine runs as root, where chmod restrictions have
no effect). Added os.Getuid() == 0 skip guards to:
- internal/gradle: TestWriteVersionReadOnly
- internal/gitutil: TestLatestTagTagsIterFails (replaced broken skip logic
  that only fired if Chmod itself errored)
- cmd: TestInitConfigWriteFails, TestRunLatestTagFails

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 21:38:26 +02:00
k3nny a4cd00cc4d test(ci): skip chmod-dependent tests when running as root
ci / vet, staticcheck, test, build (push) Failing after 2m54s
Docker CI containers run as root by default (golang:1.26-alpine), where
os.Chmod has no effect and permission restrictions don't apply. Four
tests were failing because they relied on chmod to force error paths:

- gradle: TestWriteVersionReadOnly
- cmd:    TestInitConfigWriteFails, TestRunLatestTagFails
- gitutil: TestLatestTagTagsIterFails (had broken skip logic that only
  fired if Chmod itself errored, which never happens as root)

Replace all four with an upfront os.Getuid() == 0 check so they are
skipped cleanly in root environments and still run (and must pass) on
non-root local development.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 21:10:41 +02:00
k3nny dfdf2b019a feat(gradle): release v1.6.0 — Gradle build file version bump
ci / vet, staticcheck, test, build (push) Failing after 3m1s
release / Build and publish release (push) Successful in 5m1s
Add internal/gradle package with ReadVersion and WriteVersion for
build.gradle (Groovy DSL, single-quoted) and build.gradle.kts (Kotlin
DSL, double-quoted). Quote style is preserved on write. regexp.QuoteMeta
ensures version strings with dots or special characters are safe.

Config follows the established multi-value pattern:
- gradle.build_file: single path (opt-in, no default)
- gradle.build_files: list for multi-module projects (overrides build_file)
- --gradle flag overrides build_file and clears build_files

100% per-package statement coverage maintained across all 13 packages;
FuzzReadVersion and FuzzWriteVersion added per fuzzing guidelines.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v1.6.0
2026-07-11 17:59:13 +02:00
k3nny e2d4214405 docs(releaser): release v1.5.1 — documentation site, fuzzing completeness
ci / vet, staticcheck, test, build (push) Failing after 3m50s
- Add Hugo + Geekdoc documentation site (docs/): installation, CLI
  reference, configuration, CI integration, and changelog pages; explicit
  menu bundle nav so all pages appear in the sidebar on every page
- Add Gitea CI workflow (.gitea/workflows/docs.yml): builds on push to
  main when docs/** changes, deploys minified site to gh-pages branch
- Add docs:setup / docs:serve / docs:build Taskfile tasks; theme bundle
  downloaded at build time (not committed)
- Add FuzzUpdate to internal/changelog and FuzzWriteVersion to
  internal/node to complete fuzz coverage for all file-rewriting packages
- Add fuzzing completeness guidelines to CLAUDE.md: authoritative table,
  exempt-package rationale, seed corpus rules

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 17:47:26 +02:00
k3nny f07220b0c6 feat(releaser): release v1.5.0 — Node.js, multi-module Maven, configurable bump rules
ci / vet, staticcheck, test, build (push) Failing after 4m11s
release / Build and publish release (push) Successful in 5m7s
- Add internal/node package: reads/writes package.json version (single or
  multi-path via node.package_json / node.package_jsons)
- Add maven.pom_paths support: update multiple pom.xml files in one release
  commit; pom_paths overrides pom_path; --pom flag clears pom_paths
- Add git.bump_rules config: per-type control of which version component bumps
  (breaking/feat/fix accept "patch" or "minor"); wired through version.Next()
  as a new sixth parameter
- Extract injectable function vars (absPath, gitAllCommits, gitCommitsSince,
  gitCommitFiles) to enable error-path testing without interfaces
- Achieve 100% per-package statement coverage across all 12 packages

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v1.5.0
2026-07-11 16:59:28 +02:00
k3nny 5af107b06d feat(releaser): release v1.4.0 — GitHub, SSH agent, configurable bumps
ci / vet, staticcheck, test, build (push) Successful in 3m54s
release / Build and publish release (push) Successful in 4m11s
- GitHub release support: internal/ghclient (no SDK, minimal HTTP client);
  GITHUB_TOKEN env var; github.token/github.repo config; GitHub takes
  precedence over GitLab when both are configured; publisher interface
  (releasePublisher) in cmd/main.go makes providers interchangeable
- SSH agent push: gitutil.Push() now tries gitssh.NewSSHAgentAuth for
  git@/ssh:// remotes before falling back to the system git binary
- --release-env-file flag: override dotenv artifact path; pass "" to disable
- git.releasable_types config: filter which commit types trigger a bump
  (defaults to fix, feat, breaking); useful for maintenance branches
- commits.Group(), ExtractSubject(), ReleasableSet() exported helpers:
  notes.go and changelog.go now delegate to these instead of duplicating
- CHANGELOG deduplication guard: changelog.Update() is idempotent — skips
  write if ## [version] section already exists
- Always load config sources: LoadWithSources() called unconditionally;
  removes the dual config path that previously only tracked sources in
  --verbose mode
- .releaser.gitlab-ci.yml: adds artifacts: reports: dotenv: release.env

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v1.4.0
2026-07-11 00:15:09 +02:00
k3nny 62a702fb89 feat(releaser): release v1.3.0 — release.env dotenv artifact
ci / vet, staticcheck, test, build (push) Successful in 2m48s
release / Build and publish release (push) Successful in 4m35s
Documents the release.env feature: a NEXT_VERSION=<tag> file written
to the repo root on every real release, intended as a GitLab CI dotenv
artifact for passing the version to downstream pipeline jobs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v1.3.0
2026-07-07 13:57:06 +02:00
k3nny 2614f23856 feat(releaser): write release.env dotenv artifact on every release
ci / vet, staticcheck, test, build (push) Successful in 3m9s
After the next version is determined and dry-run is confirmed off,
release.env is written to the repository root:

  NEXT_VERSION=<nextTag>

This file is not committed — it is left as an untracked artifact so
GitLab CI can expose it as a dotenv artifact and pass NEXT_VERSION to
downstream jobs (e.g. deploy, notify).

The file is skipped in --dry-run mode. Two tests added:
TestRunReleaseEnv and TestRunReleaseEnvDryRun.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 13:54:38 +02:00
k3nny 12cb3a71af feat(releaser): release v1.2.0 — verbose, colored output, no-v default
ci / vet, staticcheck, test, build (push) Successful in 3m18s
release / Build and publish release (push) Successful in 4m46s
- --verbose flag: config source table, per-commit type analysis, version
  decision explanation; output always to stderr
- Colored structured output: logStep/logDone/logWarn symbols, ▸ verbose
  section headers, TTY-aware ANSI colors (NO_COLOR / TERM=dumb respected)
- Name + version header printed at the start of every invocation
- Default tag_prefix changed from "v" to "" (bare 1.2.3 tags by default)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v1.2.0
2026-07-07 12:01:51 +02:00
k3nny 16b25da396 feat(config): change default tag_prefix to empty (no prefix)
ci / vet, staticcheck, test, build (push) Successful in 3m35s
Tags are now bare version numbers by default (e.g. 1.2.3).
Set tag_prefix: "v" in .releaser.yml or pass --tag-prefix v to opt in
to the v-prefixed convention.

Updated all affected tests, the .releaser.yml template comment, and
the README configuration reference.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 11:58:29 +02:00
k3nny 6984fcc547 feat(ui): print releaser name and version header on every run
ci / vet, staticcheck, test, build (push) Successful in 3m28s
Adds a logHeader() helper that prints "releaser  v<version>" to stderr
at the start of every invocation, before any other output.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 11:53:22 +02:00
k3nny 153d65bc53 feat(ui): add colored, structured CLI output
ci / vet, staticcheck, test, build (push) Successful in 3m15s
Replace flat "info:" / "warning:" stderr lines with:
- logStep (·), logDone (✓), logWarn (!) prefix symbols
- ANSI colors when stderr is a TTY; auto-disabled via NO_COLOR or TERM=dumb
- Verbose mode uses ▸ section headers (configuration / branch / commits / version)
- Config table source tags colored: dim=[default], bold=[config file],
  cyan=[env:], green=[flag:]
- Commit table in verbose mode: type column colored by kind (cyan=feat,
  green=fix, red=breaking), ignored commits dimmed
- New cmd/ui.go holds all color helpers (paint, logStep, logDone, logWarn,
  logSection, fmtSource); removes the vlog() helper

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 11:46:42 +02:00
k3nny 46a10c70dc feat(releaser): add --verbose flag for configuration and decision tracing
ci / vet, staticcheck, test, build (push) Successful in 3m10s
- Prints a configuration table on startup showing each key, its value,
  and the source (default / config file / env: VARNAME / flag: --name)
- Lists every commit since the last tag with its parsed type and
  the version-bump decision (feat/fix/breaking → patch bump, or ignored)
- Explains the final version choice: highest commit type → next tag
- All verbose output goes to stderr so it never pollutes stdout captures
- Sources tracking wired through config.LoadWithSources and
  ApplyEnvWithSources; LoadWithSources uses a two-pass approach to
  detect which YAML fields were explicitly set vs defaulted

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 11:35:22 +02:00
k3nny 5d0489dd71 feat(releaser): CHANGELOG auto-update, --init, and --changelog-file flags
ci / vet, staticcheck, test, build (push) Successful in 3m30s
release / Build and publish release (push) Successful in 4m39s
- Automatically write/update CHANGELOG.md on every release, grouped by
  Breaking Changes / Added / Fixed; file is created if missing and the
  new section is committed alongside pom.xml in the release commit
- Add --init flag: scaffolds a default .releaser.yml in the repo root
- Add --changelog-file flag: override the default CHANGELOG.md path
- Add CommitFiles() to gitutil so pom.xml and CHANGELOG.md are staged
  in a single commit
- Fix HTTPS push when no token is set: delegate to the git CLI so that
  system credential helpers, SSH agents, and netrc are honoured

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v1.1.0
2026-07-07 11:18:27 +02:00
k3nny 6ffe282105 fix(gitutil): fall back to git CLI for push when no token is set
ci / vet, staticcheck, test, build (push) Successful in 4m9s
release / Build and publish release (push) Successful in 5m28s
go-git's HTTPS transport does not use the system credential store,
so pushes to remotes that require credentials fail silently or with
"authentication required" when no token is provided. When token is
empty, delegate to the system git binary so that credential helpers,
SSH agents, and netrc all work as expected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v1.0.2
2026-07-07 01:02:37 +02:00
k3nny 0dc6d0747d feat(releaser): add --no-release flag to skip GitLab release creation
ci / vet, staticcheck, test, build (push) Successful in 3m18s
release / Build and publish release (push) Successful in 4m16s
Pushes the commit and tag as normal but exits before calling the GitLab
API. Useful when the project is hosted on a non-GitLab forge (e.g.
Gitea) where the release is handled by a separate CI workflow triggered
on the tag push.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v1.0.1
2026-07-07 00:52:11 +02:00
k3nny 7fdf5ddcf3 fix(maven): skip pom.xml update when file does not exist
ci / vet, staticcheck, test, build (push) Successful in 3m3s
release / Build and publish release (push) Successful in 4m10s
If pom.xml (or the configured maven.pom_path) is absent, releaser now
logs a notice and proceeds to tag and push without failing. This makes
the tool usable in non-Maven projects. An os.Stat error that is not
ErrNotExist (e.g. permission denied) still surfaces as an error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v1.0.0
2026-07-07 00:33:57 +02:00
k3nny c92164eb37 fix(ci): fix build step output path conflict
ci / vet, staticcheck, test, build (push) Successful in 2m47s
go build ./cmd/... tried to write a binary named "cmd" which conflicts
with the source directory of the same name; pass -o /dev/null so the
build step only verifies compilation without writing output.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 00:18:04 +02:00
k3nny f0723e706a feat(releaser): initial release v0.4.0
ci / vet, staticcheck, test, build (push) Failing after 3m26s
release / Build and publish release (push) Successful in 4m28s
Complete GitFlow release automation tool for Conventional Commits workflows:

- Core pipeline: branch parsing, tag discovery, commit analysis, version bump
- Maven pom.xml read/write, git commit/tag, HTTPS push with token auth
- GitLab release creation via API with auto-generated release notes
- Configurable via .releaser.yml (tag_prefix, branch_pattern, commit_message, pom_path, gitlab)
- CLI flags: --dry-run, --no-push, --no-commit, --tag-only, --branch, --pom, --tag-prefix, --branch-pattern
- Dockerfile (multi-stage Alpine), .releaser.gitlab-ci.yml reusable template
- Gitea CI (vet + staticcheck + test + build) and release (5-platform cross-compilation) workflows
- Taskfile with build/test/cov/lint/fuzz/ci/docker tasks
- 96% test coverage with real in-memory git repos and fuzz tests for all parsers

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v0.4.0
2026-07-07 00:07:53 +02:00