diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 82b5fc03..3ad1e55e 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -26,4 +26,4 @@ Fixes # - [ ] Added/updated tests - [ ] Lint/format passes (`golangci-lint run`) - [ ] Updated documentation (if applicable) -- [ ] Added an entry to `CHANGELOG.md` under `[Unreleased]` (for user-facing changes) +- [ ] Added a Changie changelog fragment for user-facing changes (`changie new`, see [docs/release.md](../docs/release.md)) — or N/A (docs/tests/chore only) diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml deleted file mode 100644 index 31a1b03a..00000000 --- a/.github/release-drafter.yml +++ /dev/null @@ -1,61 +0,0 @@ -name-template: "v$RESOLVED_VERSION" -tag-template: "v$RESOLVED_VERSION" - -categories: - - title: "Features" - labels: - - "feature" - - "enhancement" - - title: "Bug Fixes" - labels: - - "bug" - - "fix" - - title: "Documentation" - labels: - - "documentation" - - title: "Maintenance" - labels: - - "chore" - - "dependencies" - -change-template: "- $TITLE @$AUTHOR (#$NUMBER)" -change-title-escapes: '\<*_&' - -version-resolver: - major: - labels: - - "breaking" - minor: - labels: - - "feature" - - "enhancement" - patch: - labels: - - "bug" - - "fix" - - "chore" - - "documentation" - - "dependencies" - default: patch - -autolabeler: - - label: "documentation" - files: - - "docs/**/*" - - "*.md" - - label: "chore" - title: - - "/^chore(\\(.+\\))?:/i" - - label: "bug" - title: - - "/^fix(\\(.+\\))?:/i" - - label: "feature" - title: - - "/^feat(\\(.+\\))?:/i" - -template: | - ## What is changed - - $CHANGES - - **Full changelog**: https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...v$RESOLVED_VERSION diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml deleted file mode 100644 index ff0b2c68..00000000 --- a/.github/workflows/release-drafter.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Release Drafter - -on: - push: - branches: [main] - pull_request: - types: [opened, reopened, synchronize] - -permissions: - contents: read - -jobs: - update_release_draft: - permissions: - contents: write - pull-requests: write - runs-on: ubuntu-latest - steps: - - uses: release-drafter/release-drafter@a6a982fee9675c45c1765e9fa5308f7d6c3ecbd4 # v7.2.0 - with: - config-name: release-drafter.yml - commitish: main - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f9abafcb..ecc5e11b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,7 +26,9 @@ Thanks for your interest in contributing! This file is a short pointer — the f ## Commit message style -Conventional prefixes are preferred: `feat:`, `fix:`, `chore:`, `docs:`, `test:`, `refactor:`. This helps release-drafter categorize changes automatically. +Conventional prefixes are preferred: `feat:`, `fix:`, `chore:`, `docs:`, `test:`, `refactor:`. + +Release notes are **not** generated from commits — they come from [Changie](https://changie.dev) fragments. Add one for any user-facing change with `changie new` (see [docs/release.md](docs/release.md)). ## License of Contributions diff --git a/docs/README.md b/docs/README.md index 73f51300..ac6ff33b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -28,6 +28,7 @@ Located under [`services/`](services/): ## Contributing - **[Contributing Guide](contributing.md)** — dev setup, testing, codegen, adding new services +- **[Releasing](release.md)** — Changie + GoReleaser release process, versioning, dry runs - Root-level pointers: [CONTRIBUTING.md](../CONTRIBUTING.md), [CODE_OF_CONDUCT.md](../CODE_OF_CONDUCT.md), [SECURITY.md](../SECURITY.md), [SUPPORT.md](../SUPPORT.md) ## Meta diff --git a/docs/release.md b/docs/release.md new file mode 100644 index 00000000..76212757 --- /dev/null +++ b/docs/release.md @@ -0,0 +1,94 @@ +# Releasing DevCloud + +DevCloud ships versioned releases through **[Changie](https://changie.dev)** (changelog +management) and **[GoReleaser](https://goreleaser.com)** (build + publish). Release notes +are authored as Changie fragments during development, batched into a version file, and +handed to GoReleaser at tag time — commits and PR labels are **not** used to generate +release notes. + +Versions follow [Semantic Versioning](https://semver.org): `vMAJOR.MINOR.PATCH`. + +## Two pipelines + +| Pipeline | Trigger | What it produces | Workflow | +|----------|---------|------------------|----------| +| **Release** | pushing a `v*` tag (or manual dispatch) | GitHub Release with binaries, checksums, and versioned `*-alpine` container images | [`.github/workflows/release.yml`](../.github/workflows/release.yml) | +| **CD** | every successful CI run on a push | rolling multi-arch `latest` / branch container images to GHCR | [`.github/workflows/cd.yml`](../.github/workflows/cd.yml) | + +CD keeps `ghcr.io/skyoo2003/devcloud:latest` current with `main`. The Release pipeline is +what produces an actual tagged, downloadable release. This document covers the Release pipeline. + +## During development: add a changelog fragment + +Any user-facing change should carry a Changie fragment. From the repo root: + +```sh +changie new +``` + +You'll be prompted for a **kind** (`Added`, `Changed`, `Deprecated`, `Removed`, `Fixed`, +`Security`, `Documentation`), a one-line **body**, and the **issue number**. This writes a +small YAML file under `changes/unreleased/`. Commit it alongside your code change. + +Config lives in [`.changie.yaml`](../.changie.yaml). + +## Cutting a release + +1. **Make sure `main` is green** and holds all changes you want in the release. + +2. **Batch the unreleased fragments** into a version file. Pick the next version per SemVer: + + ```sh + changie batch v0.3.0 + ``` + + This consumes everything in `changes/unreleased/` and writes `changes/v0.3.0.md`. + +3. **Merge into the changelog:** + + ```sh + changie merge + ``` + + This regenerates [`CHANGELOG.md`](../CHANGELOG.md) from all version files. + +4. **Commit** the generated files: + + ```sh + git add changes/ CHANGELOG.md + git commit -m "chore(release): v0.3.0" + git push origin main + ``` + +5. **Tag and push.** The tag name **must** match the batched version — the Release workflow + fails if `changes/.md` does not exist. + + ```sh + git tag v0.3.0 + git push origin v0.3.0 + ``` + +Pushing the tag triggers the Release workflow. It will: + +- verify `changes/v0.3.0.md` exists (guard against tagging without release notes), +- run GoReleaser, which builds binaries for **darwin/linux/windows × amd64/arm64**, packages + them as `tar.gz` (`zip` on Windows) with `LICENSE`/`README.md`/`CHANGELOG.md`, and generates + a SHA-256 `CHECKSUMS` file, +- build and push `*-alpine` container images to `ghcr.io/skyoo2003/devcloud`, +- publish a **GitHub Release** whose notes come from `changes/v0.3.0.md` + (`--release-notes`, `mode: replace`). + +GoReleaser config: [`.goreleaser.yaml`](../.goreleaser.yaml). + +## Dry run + +To validate the build without publishing, run the workflow manually from the Actions tab +(**Release → Run workflow**) with a tag and `dry_run: true`. This runs GoReleaser in +`--snapshot` mode: it builds artifacts and uploads them to the run, but publishes nothing to +GHCR or GitHub Releases. + +## Requirements recap + +- The tag (`v0.3.0`) and the fragment file (`changes/v0.3.0.md`) must match exactly. +- `changie batch` + `changie merge` must be committed **before** the tag is pushed. +- No manual GitHub Release editing — release notes are owned by Changie fragments.