Skip to content

Commit 3c0644a

Browse files
authored
feat: unified GitHub release, server change tracking, and enhanced release PR (#3085)
- Add .server-changes/ convention for tracking server-only changes - Create scripts/enhance-release-pr.mjs to deduplicate and categorize changeset PR body - Create scripts/generate-github-release.mjs to format unified GitHub release body - Change release.yml to create one unified GitHub release instead of per-package releases - Add update-release job to patch Docker image link after images are pushed to GHCR - Update changesets-pr.yml to trigger on .server-changes, enhance PR body, and clean up consumed files - Document server changes in CLAUDE.md, CONTRIBUTING.md, CHANGESETS.md, and RELEASE.md
1 parent 19733c8 commit 3c0644a

File tree

10 files changed

+796
-20
lines changed

10 files changed

+796
-20
lines changed

.github/workflows/changesets-pr.yml

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ on:
77
paths:
88
- "packages/**"
99
- ".changeset/**"
10+
- ".server-changes/**"
1011
- "package.json"
1112
- "pnpm-lock.yaml"
1213

@@ -50,7 +51,7 @@ jobs:
5051
env:
5152
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
5253

53-
- name: Update PR title with version
54+
- name: Update PR title and enhance body
5455
if: steps.changesets.outputs.published != 'true'
5556
env:
5657
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -61,6 +62,15 @@ jobs:
6162
# we arbitrarily reference the version of the cli package here; it is the same for all package releases
6263
VERSION=$(git show origin/changeset-release/main:packages/cli-v3/package.json | jq -r '.version')
6364
gh pr edit "$PR_NUMBER" --title "chore: release v$VERSION"
65+
66+
# Enhance the PR body with a clean, deduplicated summary
67+
RAW_BODY=$(gh pr view "$PR_NUMBER" --json body --jq '.body')
68+
ENHANCED_BODY=$(CHANGESET_PR_BODY="$RAW_BODY" node scripts/enhance-release-pr.mjs "$VERSION")
69+
if [ -n "$ENHANCED_BODY" ]; then
70+
gh api repos/triggerdotdev/trigger.dev/pulls/"$PR_NUMBER" \
71+
-X PATCH \
72+
-f body="$ENHANCED_BODY"
73+
fi
6474
fi
6575
6676
update-lockfile:
@@ -88,15 +98,26 @@ jobs:
8898
- name: Install and update lockfile
8999
run: pnpm install --no-frozen-lockfile
90100

91-
- name: Commit and push lockfile
101+
- name: Clean up consumed .server-changes/ files
92102
run: |
93103
set -e
94-
if git diff --quiet pnpm-lock.yaml; then
95-
echo "No lockfile changes"
96-
else
97-
git config user.name "github-actions[bot]"
98-
git config user.email "github-actions[bot]@users.noreply.github.com"
99-
git add pnpm-lock.yaml
100-
git commit -m "chore: update lockfile for release"
104+
shopt -s nullglob
105+
files=(.server-changes/*.md)
106+
for f in "${files[@]}"; do
107+
if [ "$(basename "$f")" != "README.md" ]; then
108+
git rm --ignore-unmatch "$f"
109+
fi
110+
done
111+
112+
- name: Commit and push lockfile + server-changes cleanup
113+
run: |
114+
set -e
115+
git config user.name "github-actions[bot]"
116+
git config user.email "github-actions[bot]@users.noreply.github.com"
117+
git add pnpm-lock.yaml
118+
if ! git diff --cached --quiet; then
119+
git commit -m "chore: update lockfile and clean up .server-changes/ for release"
101120
git push origin changeset-release/main
121+
else
122+
echo "No changes to commit"
102123
fi

.github/workflows/release.yml

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ jobs:
111111
uses: changesets/action@v1
112112
with:
113113
publish: pnpm run changeset:release
114-
createGithubReleases: true
114+
createGithubReleases: false
115115
env:
116116
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
117117

@@ -122,6 +122,19 @@ jobs:
122122
package_version=$(echo '${{ steps.changesets.outputs.publishedPackages }}' | jq -r '.[0].version')
123123
echo "package_version=${package_version}" >> "$GITHUB_OUTPUT"
124124
125+
- name: Create unified GitHub release
126+
if: steps.changesets.outputs.published == 'true'
127+
env:
128+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
129+
RELEASE_PR_BODY: ${{ github.event.pull_request.body }}
130+
run: |
131+
VERSION="${{ steps.get_version.outputs.package_version }}"
132+
node scripts/generate-github-release.mjs "$VERSION" > /tmp/release-body.md
133+
gh release create "v${VERSION}" \
134+
--title "trigger.dev v${VERSION}" \
135+
--notes-file /tmp/release-body.md \
136+
--target main
137+
125138
- name: Create and push Docker tag
126139
if: steps.changesets.outputs.published == 'true'
127140
run: |
@@ -140,6 +153,47 @@ jobs:
140153
with:
141154
image_tag: v${{ needs.release.outputs.published_package_version }}
142155

156+
# After Docker images are published, update the GitHub release with the exact GHCR tag URL.
157+
# The GHCR package version ID is only known after the image is pushed, so we query for it here.
158+
update-release:
159+
name: 🔗 Update release Docker link
160+
needs: [release, publish-docker]
161+
if: needs.release.outputs.published == 'true'
162+
runs-on: ubuntu-latest
163+
permissions:
164+
contents: write
165+
packages: read
166+
steps:
167+
- name: Update GitHub release with Docker image link
168+
env:
169+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
170+
run: |
171+
set -e
172+
VERSION="${{ needs.release.outputs.published_package_version }}"
173+
TAG="v${VERSION}"
174+
175+
# Query GHCR for the version ID matching this tag
176+
VERSION_ID=$(gh api --paginate -H "Accept: application/vnd.github+json" \
177+
/orgs/triggerdotdev/packages/container/trigger.dev/versions \
178+
--jq ".[] | select(.metadata.container.tags[] == \"${TAG}\") | .id" \
179+
| head -1)
180+
181+
if [ -z "$VERSION_ID" ]; then
182+
echo "Warning: Could not find GHCR version ID for tag ${TAG}, skipping update"
183+
exit 0
184+
fi
185+
186+
DOCKER_URL="https://github.com/triggerdotdev/trigger.dev/pkgs/container/trigger.dev/${VERSION_ID}?tag=${TAG}"
187+
GENERIC_URL="https://github.com/triggerdotdev/trigger.dev/pkgs/container/trigger.dev"
188+
189+
# Get current release body and replace the generic link with the tag-specific one.
190+
# Use word boundary after GENERIC_URL (closing paren) to avoid matching URLs that
191+
# already have a version ID appended (idempotent on re-runs).
192+
gh release view "${TAG}" --json body --jq '.body' > /tmp/release-body.md
193+
sed -i "s|${GENERIC_URL})|${DOCKER_URL})|g" /tmp/release-body.md
194+
195+
gh release edit "${TAG}" --notes-file /tmp/release-body.md
196+
143197
# The prerelease job needs to be on the same workflow file due to a limitation related to how npm verifies OIDC claims.
144198
prerelease:
145199
name: 🧪 Prerelease

.server-changes/.gitkeep

Whitespace-only changes.

.server-changes/README.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Server Changes
2+
3+
This directory tracks changes to server-only components (webapp, supervisor, coordinator, etc.) that are not captured by changesets. Changesets only track published npm packages — server changes would otherwise go undocumented.
4+
5+
## When to add a file
6+
7+
**Server-only PRs**: If your PR only changes `apps/webapp/`, `apps/supervisor/`, `apps/coordinator/`, or other server components (and does NOT change anything in `packages/`), add a `.server-changes/` file.
8+
9+
**Mixed PRs** (both packages and server): Just add a changeset as usual. No `.server-changes/` file needed — the changeset covers it.
10+
11+
**Package-only PRs**: Just add a changeset as usual.
12+
13+
## File format
14+
15+
Create a markdown file with a descriptive name:
16+
17+
```
18+
.server-changes/fix-batch-queue-stalls.md
19+
```
20+
21+
With this format:
22+
23+
```markdown
24+
---
25+
area: webapp
26+
type: fix
27+
---
28+
29+
Speed up batch queue processing by removing stalls and fixing retry race
30+
```
31+
32+
### Fields
33+
34+
- **area** (required): `webapp` | `supervisor` | `coordinator` | `kubernetes-provider` | `docker-provider`
35+
- **type** (required): `feature` | `fix` | `improvement` | `breaking`
36+
37+
### Description
38+
39+
The body text (below the frontmatter) is a one-line description of the change. Keep it concise — it will appear in release notes.
40+
41+
## Lifecycle
42+
43+
1. Engineer adds a `.server-changes/` file in their PR
44+
2. Files accumulate on `main` as PRs merge
45+
3. The changeset release PR includes these in its summary
46+
4. After the release merges, CI cleans up the consumed files
47+
48+
## Examples
49+
50+
**New feature:**
51+
52+
```markdown
53+
---
54+
area: webapp
55+
type: feature
56+
---
57+
58+
TRQL query language and the Query page
59+
```
60+
61+
**Bug fix:**
62+
63+
```markdown
64+
---
65+
area: webapp
66+
type: fix
67+
---
68+
69+
Fix schedule limit counting for orgs with custom limits
70+
```
71+
72+
**Improvement:**
73+
74+
```markdown
75+
---
76+
area: webapp
77+
type: improvement
78+
---
79+
80+
Use the replica for API auth queries to reduce primary load
81+
```

CHANGESETS.md

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,49 @@
1-
# Changesets
1+
# Changesets and Server Changes
22

3-
Trigger.dev uses [changesets](https://github.com/changesets/changesets) to manage updated our packages and releasing them to npm.
3+
Trigger.dev uses [changesets](https://github.com/changesets/changesets) to manage package versions and releasing them to npm. For server-only changes, we use a lightweight `.server-changes/` convention.
44

5-
## Adding a changeset
5+
## Adding a changeset (package changes)
66

77
To add a changeset, use `pnpm run changeset:add` and follow the instructions [here](https://github.com/changesets/changesets/blob/main/docs/adding-a-changeset.md). Please only ever select one of our public packages when adding a changeset.
88

9-
## Release instructions (local only)
9+
## Adding a server change (server-only changes)
1010

11-
Based on the instructions [here](https://github.com/changesets/changesets/blob/main/docs/intro-to-using-changesets.md)
11+
If your PR only changes server components (`apps/webapp/`, `apps/supervisor/`, etc.) and does NOT change any published packages, add a `.server-changes/` file instead of a changeset:
1212

13-
1. Run `pnpm run changeset:version`
14-
2. Run `pnpm run changeset:release`
13+
```sh
14+
cat > .server-changes/fix-batch-queue-stalls.md << 'EOF'
15+
---
16+
area: webapp
17+
type: fix
18+
---
19+
20+
Speed up batch queue processing by removing stalls and fixing retry race
21+
EOF
22+
```
23+
24+
- `area`: `webapp` | `supervisor` | `coordinator` | `kubernetes-provider` | `docker-provider`
25+
- `type`: `feature` | `fix` | `improvement` | `breaking`
26+
27+
For **mixed PRs** (both packages and server): just add a changeset. No `.server-changes/` file needed.
28+
29+
See `.server-changes/README.md` for full documentation.
30+
31+
## When to add which
32+
33+
| PR changes | What to add |
34+
|---|---|
35+
| Only packages (`packages/`) | Changeset (`pnpm run changeset:add`) |
36+
| Only server (`apps/`) | `.server-changes/` file |
37+
| Both packages and server | Just the changeset |
1538

1639
## Release instructions (CI)
1740

1841
Please follow the best-practice of adding changesets in the same commit as the code making the change with `pnpm run changeset:add`, as it will allow our release.yml CI workflow to function properly:
1942

20-
- Anytime new changesets are added in a commit in the `main` branch, the [release.yml](./.github/workflows/release.yml) workflow will run and will automatically create/update a PR with a fresh run of `pnpm run changeset:version`.
21-
- When the version PR is merged into `main`, the release.yml workflow will automatically run `pnpm run changeset:release` to build and release packages to npm.
43+
- Anytime new changesets are added in a commit in the `main` branch, the [changesets-pr.yml](./.github/workflows/changesets-pr.yml) workflow will run and will automatically create/update a PR with a fresh run of `pnpm run changeset:version`.
44+
- The release PR body is automatically enhanced with a clean, deduplicated summary that includes both package changes and `.server-changes/` entries.
45+
- Consumed `.server-changes/` files are removed on the `changeset-release/main` branch — the same way changesets deletes `.changeset/*.md` files. When the release PR merges, they're gone from main.
46+
- When the version PR is merged into `main`, the [release.yml](./.github/workflows/release.yml) workflow will automatically build, release packages to npm, and create a single unified GitHub release.
2247

2348
## Pre-release instructions
2449

CLAUDE.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ containerTest("should use both", async ({ prisma, redisOptions }) => {
6767
});
6868
```
6969

70-
### Changesets
70+
### Changesets and Server Changes
7171

7272
When modifying any public package (`packages/*` or `integrations/*`), add a changeset:
7373

@@ -79,6 +79,25 @@ pnpm run changeset:add
7979
- Confirm with maintainers before selecting **minor** (new features)
8080
- **Never** select major (breaking changes) without explicit approval
8181

82+
When modifying only server components (`apps/webapp/`, `apps/supervisor/`, etc.) with no package changes, add a `.server-changes/` file instead:
83+
84+
```bash
85+
# Create a file with a descriptive name
86+
cat > .server-changes/fix-batch-queue-stalls.md << 'EOF'
87+
---
88+
area: webapp
89+
type: fix
90+
---
91+
92+
Speed up batch queue processing by removing stalls and fixing retry race
93+
EOF
94+
```
95+
96+
- **area**: `webapp` | `supervisor` | `coordinator` | `kubernetes-provider` | `docker-provider`
97+
- **type**: `feature` | `fix` | `improvement` | `breaking`
98+
- **Mixed PRs** (both packages and server): just the changeset is enough, no `.server-changes/` file needed
99+
- See `.server-changes/README.md` for full documentation
100+
82101
## Architecture Overview
83102

84103
### Apps

CONTRIBUTING.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,39 @@ You will be prompted to select which packages to include in the changeset. Only
267267

268268
Most of the time the changes you'll make are likely to be categorized as patch releases. If you feel like there is the need for a minor or major release of the package based on the changes being made, add the changeset as such and it will be discussed during PR review.
269269

270+
## Adding server changes
271+
272+
Changesets only track published npm packages. If your PR only changes server components (`apps/webapp/`, `apps/supervisor/`, `apps/coordinator/`, etc.) with no package changes, add a `.server-changes/` file so the change appears in release notes.
273+
274+
Create a markdown file with a descriptive name:
275+
276+
```sh
277+
cat > .server-changes/fix-batch-queue-stalls.md << 'EOF'
278+
---
279+
area: webapp
280+
type: fix
281+
---
282+
283+
Speed up batch queue processing by removing stalls and fixing retry race
284+
EOF
285+
```
286+
287+
**Fields:**
288+
- `area` (required): `webapp` | `supervisor` | `coordinator` | `kubernetes-provider` | `docker-provider`
289+
- `type` (required): `feature` | `fix` | `improvement` | `breaking`
290+
291+
The body text (below the frontmatter) is a one-line description of the change. Keep it concise — it will appear in release notes.
292+
293+
**When to add which:**
294+
295+
| PR changes | What to add |
296+
|---|---|
297+
| Only packages (`packages/`) | Changeset |
298+
| Only server (`apps/`) | `.server-changes/` file |
299+
| Both packages and server | Just the changeset |
300+
301+
See `.server-changes/README.md` for more details.
302+
270303
## Troubleshooting
271304

272305
### EADDRINUSE: address already in use :::3030

RELEASE.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,28 @@
11
## Guide on releasing a new version
22

3+
### Automated release (v4+)
4+
5+
Releases are fully automated via CI:
6+
7+
1. PRs merge to `main` with changesets (for package changes) and/or `.server-changes/` files (for server-only changes).
8+
2. The [changesets-pr.yml](./.github/workflows/changesets-pr.yml) workflow automatically creates/updates the `changeset-release/main` PR with version bumps and an enhanced summary of all changes. Consumed `.server-changes/` files are removed on the release branch (same approach changesets uses for `.changeset/` files — they're deleted on the branch, so merging the PR cleans them up).
9+
3. When ready to release, merge the changeset release PR into `main`.
10+
4. The [release.yml](./.github/workflows/release.yml) workflow automatically:
11+
- Publishes all packages to npm
12+
- Creates a single unified GitHub release (e.g., "trigger.dev v4.3.4")
13+
- Tags and triggers Docker image builds
14+
- After Docker images are pushed, updates the GitHub release with the exact GHCR tag link
15+
16+
### What engineers need to do
17+
18+
- **Package changes**: Add a changeset with `pnpm run changeset:add`
19+
- **Server-only changes**: Add a `.server-changes/` file (see `.server-changes/README.md`)
20+
- **Mixed PRs**: Just the changeset is enough
21+
22+
See `CHANGESETS.md` for full details on changesets and server changes.
23+
24+
### Legacy release (v3)
25+
326
1. Merge in the changeset PR into main, making sure to cancel both the release and publish github actions from that merge.
427
2. Pull the changes locally into main
528
3. Run `pnpm i` which will update the pnpm lock file with the new versions

0 commit comments

Comments
 (0)