Skip to content

Commit b95fae5

Browse files
Merge pull request #4 from pasunboneleve/dev
Use changelog-driven GitHub release notes
2 parents 9bf1573 + c990e39 commit b95fae5

6 files changed

Lines changed: 80 additions & 4 deletions

File tree

.beads/issues.jsonl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
{"id":"devloop-8km","title":"Implement config and workflow engine","description":"Load config, watch paths, classify events, and execute ordered workflows against named processes and hooks.","status":"closed","priority":2,"issue_type":"feature","owner":"1708810+dmvianna@users.noreply.github.com","created_at":"2026-03-24T01:15:00Z","created_by":"Daniel Vianna","updated_at":"2026-03-24T02:09:33Z","closed_at":"2026-03-24T02:09:33Z","close_reason":"Closed","dependencies":[{"issue_id":"devloop-8km","depends_on_id":"devloop-0nx","type":"blocks","created_at":"2026-03-24T12:15:07Z","created_by":"Daniel Vianna","metadata":"{}"}]}
33
{"id":"devloop-c6l","title":"Polish 0.8.0 release docs and test ergonomics","status":"closed","priority":2,"issue_type":"task","owner":"1708810+dmvianna@users.noreply.github.com","created_at":"2026-04-08T07:12:58Z","created_by":"Daniel Vianna","updated_at":"2026-04-08T07:20:27Z","closed_at":"2026-04-08T07:20:27Z","close_reason":"Closed"}
44
{"id":"devloop-d81","title":"Move real client config out of devloop examples","description":"Keep only generic examples in devloop and move the working blog config into the client repository root.","status":"closed","priority":2,"issue_type":"task","owner":"1708810+dmvianna@users.noreply.github.com","created_at":"2026-03-24T02:31:27Z","created_by":"Daniel Vianna","updated_at":"2026-03-24T02:39:07Z","closed_at":"2026-03-24T02:39:07Z","close_reason":"Kept only generic examples in devloop and moved the working blog config into the client repo root."}
5+
{"id":"devloop-dxz","title":"Use changelog-driven GitHub release notes and backfill old releases","status":"closed","priority":2,"issue_type":"task","owner":"1708810+dmvianna@users.noreply.github.com","created_at":"2026-04-08T08:18:49Z","created_by":"Daniel Vianna","updated_at":"2026-04-08T08:26:59Z","closed_at":"2026-04-08T08:26:59Z","close_reason":"Closed"}
56
{"id":"devloop-dzy","title":"Make client hook paths repo-relative","description":"Resolve devloop config command paths relative to the client repo or config, not the tool checkout.","status":"closed","priority":2,"issue_type":"task","owner":"1708810+dmvianna@users.noreply.github.com","created_at":"2026-03-24T02:16:34Z","created_by":"Daniel Vianna","updated_at":"2026-03-24T02:22:17Z","closed_at":"2026-03-24T02:22:17Z","close_reason":"Closed"}
67
{"id":"devloop-mml","title":"Address roborev findings on state ownership and client-specific URL composition","status":"closed","priority":1,"issue_type":"task","owner":"1708810+dmvianna@users.noreply.github.com","created_at":"2026-03-24T02:44:51Z","created_by":"Daniel Vianna","updated_at":"2026-03-24T02:53:31Z","closed_at":"2026-03-24T02:53:31Z","close_reason":"Shared session state is now owned in memory, generic state templating replaced blog-specific derivation, redundant writes are skipped, and the review job was addressed."}
78
{"id":"devloop-nmu","title":"Add blog client example and verification","description":"Create example config/hooks for the blog repo and verify the tool runs against it.","status":"closed","priority":2,"issue_type":"task","owner":"1708810+dmvianna@users.noreply.github.com","created_at":"2026-03-24T01:15:00Z","created_by":"Daniel Vianna","updated_at":"2026-03-24T02:09:33Z","closed_at":"2026-03-24T02:09:33Z","close_reason":"Closed","dependencies":[{"issue_id":"devloop-nmu","depends_on_id":"devloop-8km","type":"blocks","created_at":"2026-03-24T12:15:07Z","created_by":"Daniel Vianna","metadata":"{}"}]}

.github/workflows/linux-release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ jobs:
1515
runner: ubuntu-latest
1616
target: x86_64-unknown-linux-gnu
1717
archive_name: devloop-x86_64-unknown-linux-gnu.tar.gz
18-
generate_release_notes: true
18+
publish_release_notes: true

.github/workflows/macos-release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ jobs:
1515
runner: macos-14
1616
target: aarch64-apple-darwin
1717
archive_name: devloop-aarch64-apple-darwin.tar.gz
18-
generate_release_notes: false
18+
publish_release_notes: false

.github/workflows/release-reusable.yml

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ on:
1212
archive_name:
1313
required: true
1414
type: string
15-
generate_release_notes:
15+
publish_release_notes:
1616
required: true
1717
type: boolean
1818

@@ -56,9 +56,24 @@ jobs:
5656
cp "target/${{ inputs.target }}/release/devloop" dist/devloop
5757
tar -C dist -czf "${{ inputs.archive_name }}" devloop
5858
59+
- name: Extract release notes from changelog
60+
if: inputs.publish_release_notes
61+
shell: bash
62+
run: |
63+
set -euo pipefail
64+
./scripts/release-notes-from-changelog.sh "${GITHUB_REF_NAME#v}" "${GITHUB_REPOSITORY}" > release-notes.md
65+
5966
- name: Publish GitHub release asset
67+
if: inputs.publish_release_notes
68+
uses: softprops/action-gh-release@v2
69+
with:
70+
files: ${{ inputs.archive_name }}
71+
body_path: release-notes.md
72+
fail_on_unmatched_files: true
73+
74+
- name: Publish GitHub release asset without notes
75+
if: ${{ !inputs.publish_release_notes }}
6076
uses: softprops/action-gh-release@v2
6177
with:
6278
files: ${{ inputs.archive_name }}
63-
generate_release_notes: ${{ inputs.generate_release_notes }}
6479
fail_on_unmatched_files: true

docs/development.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@ cargo clippy --all-targets --all-features -- -D warnings
1717
checks that `devloop run` can start, begin watching, react to one file
1818
change, and shut down cleanly.
1919

20+
## Releases
21+
22+
`devloop` releases are tag-driven. Push a tag such as `v0.8.0` and the
23+
platform release workflows publish the Linux and macOS archives.
24+
25+
GitHub release notes are generated from the matching section in
26+
`CHANGELOG.md`, not from GitHub's automatic PR summary. The Linux
27+
release job publishes the changelog text and compare link; the macOS job
28+
only attaches its archive asset to that same release.
29+
2030
## Opt-in watch flake smoke
2131

2232
The repeated-edit watch flake smoke test is intentionally opt-in. It is
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
if [[ $# -lt 1 || $# -gt 2 ]]; then
5+
echo "usage: $0 <version> [repo-slug]" >&2
6+
exit 1
7+
fi
8+
9+
version="$1"
10+
repo_slug="${2:-}"
11+
changelog_path="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/CHANGELOG.md"
12+
13+
section="$(
14+
awk -v version="$version" '
15+
$0 ~ "^## \\[" version "\\] - " { in_section=1 }
16+
in_section {
17+
if ($0 ~ "^## \\[" && $0 !~ "^## \\[" version "\\] - ") {
18+
exit
19+
}
20+
print
21+
}
22+
' "$changelog_path"
23+
)"
24+
25+
if [[ -z "$section" ]]; then
26+
echo "could not find changelog section for version $version" >&2
27+
exit 1
28+
fi
29+
30+
printf '%s\n' "$section"
31+
32+
if [[ -n "$repo_slug" ]]; then
33+
previous_version="$(
34+
awk -v version="$version" '
35+
$0 ~ "^## \\[" version "\\] - " { found=1; next }
36+
found && $0 ~ /^## \[[^]]+\] - / {
37+
line = $0
38+
sub(/^## \[/, "", line)
39+
sub(/\].*/, "", line)
40+
print line
41+
exit
42+
}
43+
' "$changelog_path"
44+
)"
45+
46+
if [[ -n "$previous_version" && "$previous_version" != "Unreleased" ]]; then
47+
printf '\n**Full Changelog**: https://github.com/%s/compare/v%s...v%s\n' \
48+
"$repo_slug" "$previous_version" "$version"
49+
fi
50+
fi

0 commit comments

Comments
 (0)