Skip to content

Commit 42939c0

Browse files
Merge pull request #175 from dineshSajwan/main
chore(release): added release workflow
2 parents b1da33a + 906c83e commit 42939c0

File tree

4 files changed

+771
-0
lines changed

4 files changed

+771
-0
lines changed
Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
# Release Instructions
2+
3+
This document describes the full release process for
4+
`guidance-for-claude-code-with-amazon-bedrock`. Releases follow
5+
[Semantic Versioning](https://semver.org/spec/v2.0.0.html) and are published as
6+
[GitHub Releases](https://github.com/aws-solutions-library-samples/guidance-for-claude-code-with-amazon-bedrock/releases).
7+
8+
---
9+
10+
## Prerequisites
11+
12+
- Write access to the repository
13+
- GitHub CLI (`gh`) installed locally (optional — only needed if you want to trigger from terminal)
14+
- A `RELEASE_TOKEN` repository secret set to a Personal Access Token (PAT) with `repo` scope
15+
16+
> **Why a PAT?**
17+
> GitHub Actions' built-in `GITHUB_TOKEN` cannot trigger downstream workflows.
18+
> When `release-merge-tag.yml` pushes a tag, `release.yml` must be triggered by
19+
> that push — this only works if the push was authenticated with a PAT or GitHub
20+
> App token. Without `RELEASE_TOKEN`, the tag is created but the GitHub Release
21+
> must be published manually.
22+
>
23+
> To create the PAT: **GitHub → Settings → Developer settings → Personal access
24+
> tokens → Fine-grained tokens → New token**
25+
> Required permissions: `Contents: Read and write`, `Pull requests: Read and write`
26+
> Then add it at: **Repo → Settings → Secrets and variables → Actions →
27+
> New repository secret** → name it `RELEASE_TOKEN`.
28+
29+
---
30+
31+
## Workflow overview
32+
33+
Three workflows work together in sequence:
34+
35+
```
36+
You (manual)
37+
38+
39+
release-initiate.yml ← you trigger this
40+
│ Reads current version from source/pyproject.toml
41+
│ Computes next version (based on your choice)
42+
│ Collects commits since last release
43+
│ Inserts new section into CHANGELOG.md
44+
│ Bumps version in source/pyproject.toml
45+
│ Opens PR: "chore: release vX.Y.Z (patch|minor|major)"
46+
47+
PR reviewed & merged to main (you)
48+
49+
50+
release-merge-tag.yml ← auto, triggers on PR merge
51+
│ Reads version from source/pyproject.toml
52+
│ Creates annotated git tag vX.Y.Z
53+
│ Pushes tag to repository
54+
55+
release.yml ← auto, triggers on tag push
56+
Extracts [X.Y.Z] section from CHANGELOG.md
57+
Publishes GitHub Release with those notes
58+
Release visible at /releases
59+
```
60+
61+
---
62+
63+
## Step-by-step guide
64+
65+
### Step 1 — Decide the release type
66+
67+
Before triggering the workflow, decide which semver component to bump:
68+
69+
| Type | When to use | Example |
70+
|---|---|---|
71+
| `patch` | Bug fixes only, no new features, no breaking changes | `2.1.0``2.1.1` |
72+
| `minor` | New features added, fully backward compatible | `2.1.0``2.2.0` |
73+
| `major` | Breaking changes — existing behaviour removed or changed | `2.1.0``3.0.0` |
74+
75+
**No algorithm decides this** — you choose based on what changed. When in doubt, look at the merged PRs since the last release and apply [semver rules](https://semver.org).
76+
77+
---
78+
79+
### Step 2 — Trigger the release initiation workflow
80+
81+
**Option A — GitHub UI (recommended):**
82+
83+
1. Go to the repository on GitHub
84+
2. Click **Actions** in the top navigation
85+
3. Select **Release Initiate** from the left sidebar
86+
4. Click **Run workflow** (top right of the workflow list)
87+
5. Choose the release type from the dropdown: `patch`, `minor`, or `major`
88+
6. Click **Run workflow**
89+
90+
**Option B — GitHub CLI:**
91+
92+
```bash
93+
gh workflow run release-initiate.yml \
94+
--repo aws-solutions-library-samples/guidance-for-claude-code-with-amazon-bedrock \
95+
--ref main \
96+
--field release_type=patch
97+
```
98+
99+
Replace `patch` with `minor` or `major` as needed.
100+
101+
---
102+
103+
### Step 3 — What the workflow does automatically
104+
105+
After you click **Run workflow**, the `release-initiate.yml` workflow:
106+
107+
1. **Reads** the current version from `source/pyproject.toml` (e.g. `2.1.0`)
108+
2. **Computes** the next version (e.g. patch → `2.1.1`)
109+
3. **Collects** all commits since the last published release, grouped by conventional-commit prefix:
110+
- `feat:` commits → **Added** section
111+
- `fix:` commits → **Fixed** section
112+
- `refactor:` / `perf:` commits → **Changed** section
113+
- `chore:` / `ci:` / `docs:` commits → **Other** section
114+
4. **Inserts** a new `## [2.1.1] - YYYY-MM-DD` section at the top of `CHANGELOG.md`
115+
5. **Bumps** `version = "2.1.1"` in `source/pyproject.toml`
116+
6. **Creates** a branch named `release/YYYY.MM.YYYYMMDDhhmmss`
117+
7. **Opens** a pull request titled `chore: release v2.1.1 (patch)`
118+
8. **Closes** any previously open stale release PRs
119+
120+
The entire process takes ~60 seconds.
121+
122+
---
123+
124+
### Step 4 — Review and edit the release PR
125+
126+
Open the pull request that was just created. It contains exactly **two changed files**:
127+
128+
**`source/pyproject.toml`**
129+
```diff
130+
-version = "2.1.0"
131+
+version = "2.1.1"
132+
```
133+
134+
**`CHANGELOG.md`** (new section prepended)
135+
```diff
136+
+## [2.1.1] - 2026-03-27
137+
+
138+
+### Added
139+
+- Add Claude Opus 4.6 model support
140+
+- Add ALB JWT validation for OTEL Collector endpoint
141+
+
142+
+### Fixed
143+
+- Add two-layer caching to otel-helper to eliminate telemetry UI freezes
144+
+- Use configured inference profile for test instead of hardcoded model IDs
145+
+- Auth0 JWT issuer trailing slash
146+
+
147+
+### Other
148+
+- Add GitHub security scanning workflows (bandit, semgrep, cfn_nag, scanners)
149+
+
150+
## [2.1.0] - 2026-03-20
151+
```
152+
153+
**Before merging:**
154+
155+
- [ ] Read through the auto-generated CHANGELOG section and clean up wording
156+
- [ ] Remove any `chore:` / `ci:` entries that are not relevant to users
157+
- [ ] Add any context that commit messages lacked (e.g. link to PR numbers)
158+
- [ ] Confirm the version bump is the correct type for the changes
159+
- [ ] Wait for all CI checks to pass (scanners, bandit, cfn_nag, semgrep)
160+
161+
You can push additional commits to the `release/*` branch to refine the notes before merging.
162+
163+
---
164+
165+
### Step 5 — Merge the PR
166+
167+
Once the release notes look good and all checks pass:
168+
169+
1. Get at least one code owner approval (per `CODEOWNERS`)
170+
2. Merge the PR using **Squash and merge** or **Merge commit** (either is fine)
171+
3. Do **not** close or delete the PR without merging — that will not trigger the tag step
172+
173+
---
174+
175+
### Step 6 — Tag is created automatically
176+
177+
`release-merge-tag.yml` fires within seconds of the merge. It:
178+
179+
1. Reads `version = "2.1.1"` from `source/pyproject.toml` on the merged commit
180+
2. Validates that tag `v2.1.1` does not already exist
181+
3. Creates an annotated tag: `git tag -a v2.1.1 -m "Release 2.1.1"`
182+
4. Pushes `v2.1.1` to the repository
183+
184+
You can watch progress at **Actions → Release Merged (tag)**.
185+
186+
---
187+
188+
### Step 7 — GitHub Release is published automatically
189+
190+
`release.yml` fires when the `v2.1.1` tag is pushed. It:
191+
192+
1. Validates the tag format matches `vMAJOR.MINOR.PATCH`
193+
2. Extracts the `## [2.1.1]` section from `CHANGELOG.md`
194+
3. Creates a **GitHub Release** titled `Release v2.1.1` with those notes
195+
196+
The release is immediately visible at:
197+
`https://github.com/aws-solutions-library-samples/guidance-for-claude-code-with-amazon-bedrock/releases`
198+
199+
You can watch progress at **Actions → Release (publish)**.
200+
201+
---
202+
203+
## Where release notes are published
204+
205+
All release notes are published to the **GitHub Releases page** only:
206+
207+
```
208+
https://github.com/aws-solutions-library-samples/guidance-for-claude-code-with-amazon-bedrock/releases
209+
```
210+
211+
The content of each release is taken directly from the matching `## [X.Y.Z]` section
212+
in `CHANGELOG.md`. Whatever you write in that section during Step 4 is exactly what
213+
appears on the releases page — no separate template or configuration needed.
214+
215+
This repo does **not** publish to PyPI, NPM, or any package registry as part of the
216+
release workflow.
217+
218+
---
219+
220+
## What happens if another PR is merged while a release PR is open
221+
222+
If someone merges a feature or fix PR to `main` while a release PR is open,
223+
`release-merge-tag.yml` automatically closes the stale release PR with a comment
224+
explaining why. You must then re-run **Release Initiate** to create a fresh release
225+
PR that includes the newly merged changes.
226+
227+
This prevents a release from being cut against a stale diff.
228+
229+
---
230+
231+
## Troubleshooting
232+
233+
### Release Initiate fails — "version not found in source/pyproject.toml"
234+
235+
The workflow reads `version = "X.Y.Z"` from `source/pyproject.toml`. If that line
236+
is missing or malformed, the workflow exits. Fix the version line in `pyproject.toml`
237+
and re-run.
238+
239+
### Release Merged (tag) fails — "Tag vX.Y.Z already exists"
240+
241+
A tag for this version was already pushed (perhaps from a previous attempt). Options:
242+
- If the previous release was published correctly, no action needed — the release is done
243+
- If you need to re-release, manually delete the tag and the GitHub Release, then re-merge
244+
245+
```bash
246+
git push --delete origin vX.Y.Z
247+
gh release delete vX.Y.Z --repo aws-solutions-library-samples/guidance-for-claude-code-with-amazon-bedrock
248+
```
249+
250+
### release.yml does not trigger after the tag is pushed
251+
252+
This happens when `RELEASE_TOKEN` is not set and the tag was pushed using the
253+
built-in `GITHUB_TOKEN`. The `GITHUB_TOKEN` cannot trigger downstream workflows.
254+
255+
**Fix:** Create a PAT as described in Prerequisites, add it as `RELEASE_TOKEN`, then
256+
manually publish the release:
257+
258+
```bash
259+
gh release create vX.Y.Z \
260+
--repo aws-solutions-library-samples/guidance-for-claude-code-with-amazon-bedrock \
261+
--title "Release vX.Y.Z" \
262+
--generate-notes
263+
```
264+
265+
### The auto-generated CHANGELOG section is empty or wrong
266+
267+
The workflow groups commits by [conventional commit](https://www.conventionalcommits.org/)
268+
prefix (`feat:`, `fix:`, `chore:`, etc.). If commits in this repo do not follow that
269+
convention, they will fall into the uncategorised bucket or be omitted. Edit the
270+
CHANGELOG section in the PR before merging — it is just a text file.
271+
272+
---
273+
274+
## Workflow diagram
275+
276+
```mermaid
277+
flowchart TD
278+
A((You\nworkflow_dispatch\npatch / minor / major)) --> B
279+
280+
B["release-initiate.yml\n─────────────────\nRead current version\nCompute next version\nCollect commits\nUpdate CHANGELOG.md\nBump pyproject.toml\nCreate release/* branch\nOpen PR"]
281+
282+
B --> C{PR reviewed\nand merged?}
283+
284+
C -->|Another PR merged first| D[Close stale release PR]
285+
D --> A
286+
287+
C -->|Yes - merged to main| E
288+
289+
E["release-merge-tag.yml\n─────────────────\nRead version from pyproject.toml\nCreate annotated tag vX.Y.Z\nPush tag"]
290+
291+
E --> F
292+
293+
F["release.yml\n─────────────────\nExtract CHANGELOG section\nPublish GitHub Release"]
294+
295+
F --> G((Release live\nat /releases))
296+
297+
style A fill:#dbeafe,stroke:#1d4ed8
298+
style C fill:#fef9c3,stroke:#ca8a04
299+
style G fill:#dcfce7,stroke:#16a34a
300+
```

0 commit comments

Comments
 (0)