Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions .github/guid-index.json
Original file line number Diff line number Diff line change
Expand Up @@ -1003,7 +1003,7 @@
"path": ".github/workflows/reusable-release.yml",
"guid": "7b8c9d0e-1f2a-3b4c-5d6e-7f8a9b0c1d2e",
"title": "Reusable Release Coordinator",
"version": "2.15.3",
"version": "2.16.0",
"header_path": ".github/workflows/reusable-release.yml",
"path_mismatch": false
},
Expand Down Expand Up @@ -1167,6 +1167,14 @@
"header_path": ".github/workflows/scripts/release-strategy.sh",
"path_mismatch": false
},
{
"path": ".github/workflows/scripts/release_workflow.py",
"guid": "dc14e86d-ff9a-4317-88de-23e0e48651d2",
"title": "release workflow",
"version": "2.3.0",
"header_path": ".github/workflows/scripts/release_workflow.py",
"path_mismatch": false
},
{
"path": ".github/workflows/scripts/test-scripts.sh",
"guid": "2e3f4a5b-6c7d-8e9f-0a1b-2c3d4e5f6a7b",
Expand Down Expand Up @@ -1547,7 +1555,7 @@
"path": "WORKFLOW_SCRIPT_USAGE_MAP.md",
"guid": "2b3c4d5e-6f7a-8b9c-0d1e-2f3a4b5c6d7e",
"title": "Workflow Script Usage Mapping",
"version": "1.0.0",
"version": "1.0.1",
"header_path": "WORKFLOW_SCRIPT_USAGE_MAP.md",
"path_mismatch": false
},
Expand Down Expand Up @@ -3011,7 +3019,7 @@
"path": "ruff.toml",
"guid": "f1a2b3c4-d5e6-789f-a012-456789abcdef",
"title": "ruff",
"version": "1.3.0",
"version": "1.4.0",
"header_path": "ruff.toml",
"path_mismatch": false
},
Expand Down Expand Up @@ -3687,6 +3695,14 @@
"header_path": "tests/workflow_scripts/test_publish_to_github_packages.py",
"path_mismatch": false
},
{
"path": "tests/workflow_scripts/test_release_workflow.py",
"guid": "543b49c0-5c64-4cea-a025-76de25f6b324",
"title": "test release workflow",
"version": "1.1.0",
"header_path": "tests/workflow_scripts/test_release_workflow.py",
"path_mismatch": false
},
{
"path": "tests/workflow_scripts/test_workflow_common.py",
"guid": "4dcbebd7-74dd-4c5f-9442-7ad2c49ea5a6",
Expand Down
126 changes: 90 additions & 36 deletions .github/workflows/reusable-release.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# file: .github/workflows/reusable-release.yml
# version: 2.15.3
# version: 2.16.0
# guid: 7b8c9d0e-1f2a-3b4c-5d6e-7f8a9b0c1d2e
# last-edited: 2026-08-30
# last-edited: 2026-10-16

name: Reusable Release Coordinator

Expand Down Expand Up @@ -646,6 +646,28 @@ jobs:
run: |
python3 "$GHCOMMON_SCRIPTS_DIR/release_workflow.py" "generate-changelog"

# The scripts are checked out at the caller's .github/ghcommon-ref.txt
# (or the fallback SHA above), separately from this workflow. A script
# from before github-common#374 emits only changelog_content, inline.
# Only then is it written to a file here. This is a separate step so
# that a current script's notes never pass through env at all (one env
# string is capped at 128 KiB, the original "Argument list too long").
- name: Write legacy inline changelog to a file
id: legacy-notes
if: steps.changelog.outputs.changelog_file == ''
env:
CHANGELOG_CONTENT: ${{ steps.changelog.outputs.changelog_content }}
run: |
set -euo pipefail
if [ -z "${CHANGELOG_CONTENT:-}" ]; then
exit 0 # nothing to fall back to; the guard below reports it
fi
echo "::warning::The ghcommon scripts ref predates github-common#374 (no changelog_file). Using the inline changelog; set .github/ghcommon-ref.txt to a newer github-common SHA."
f="${RUNNER_TEMP}/release-notes/legacy-changelog.md"
mkdir -p "$(dirname "$f")"
printf '%s\n' "$CHANGELOG_CONTENT" > "$f"
echo "changelog_file=$f" >> "$GITHUB_OUTPUT"

- name: Download all build artifacts
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
Expand Down Expand Up @@ -690,38 +712,64 @@ jobs:
echo "Remaining artifacts:"
find ./artifacts -type f 2>/dev/null | sort || true

- name: Create GitHub Release
id: release
uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3
# The notes go to the release through body_path, never `body:`. An
# action input is passed as an INPUT_* env var, and Linux caps one env
# string at 128 KiB; a ~125 KB changelog failed the release step with
# "Argument list too long" (audiobook-organizer v0.222.2, 2026-10-16).
- name: Compose release notes
id: notes
if: github.event_name != 'pull_request'
with:
tag_name: ${{ steps.version.outputs.version }}
name: ${{ steps.version.outputs.version }}
body: |
${{ steps.changelog.outputs.changelog_content }}
env:
CHANGELOG_FILE: ${{ steps.changelog.outputs.changelog_file || steps.legacy-notes.outputs.changelog_file }}
COMMIT_SHA: ${{ github.sha }}
run: |
set -euo pipefail
if [ ! -s "${CHANGELOG_FILE:-}" ]; then
echo "::error::No non-empty release notes file (changelog_file, or the legacy changelog_content). Check the Generate changelog step; if the ghcommon scripts ref is old, set .github/ghcommon-ref.txt to a current github-common SHA."
exit 1
fi
NOTES_FILE="${RUNNER_TEMP}/release-notes/body.md"
mkdir -p "$(dirname "$NOTES_FILE")"
{
cat "$CHANGELOG_FILE"
echo
cat <<'FOOTER_EOF'

## Release Assets

## Release Assets
This release includes organized packages for easy consumption:

This release includes organized packages for easy consumption:
### Binaries
Pre-built binaries for multiple platforms with SHA256 checksums:
- **Linux**: `*-linux-amd64`, `*-linux-arm64`
- **macOS**: `*-darwin-amd64`, `*-darwin-arm64`

### Binaries
Pre-built binaries for multiple platforms with SHA256 checksums:
- **Linux**: `*-linux-amd64`, `*-linux-arm64`
- **macOS**: `*-darwin-amd64`, `*-darwin-arm64`
Each binary includes a `.sha256` checksum file for verification.

Each binary includes a `.sha256` checksum file for verification.
### SDKs
- **Go SDK**: `*-go-sdk.tar.gz` / `*-go-sdk.zip`
- **Python SDK**: `*-python-sdk.tar.gz` / `*-python-sdk.zip`

### SDKs
- **Go SDK**: `*-go-sdk.tar.gz` / `*-go-sdk.zip`
- **Python SDK**: `*-python-sdk.tar.gz` / `*-python-sdk.zip`
### Documentation
- **API Documentation**: `*-docs.tar.gz` / `*-docs.zip`

### Documentation
- **API Documentation**: `*-docs.tar.gz` / `*-docs.zip`
See `MANIFEST.md` in the release assets for a complete list of all files and their sizes.

See `MANIFEST.md` in the release assets for a complete list of all files and their sizes.
---
FOOTER_EOF
printf '*Generated automatically from commit %s*\n' "$COMMIT_SHA"
} > "$NOTES_FILE"
echo "body-file=$NOTES_FILE" >> "$GITHUB_OUTPUT"
echo "Release notes: $(wc -c < "$NOTES_FILE") bytes"

---
*Generated automatically from commit ${{ github.sha }}*
- name: Create GitHub Release
id: release
uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3
if: github.event_name != 'pull_request'
with:
tag_name: ${{ steps.version.outputs.version }}
name: ${{ steps.version.outputs.version }}
body_path: ${{ steps.notes.outputs.body-file }}
draft: ${{ needs.detect-languages.outputs.auto-draft }}
prerelease: ${{ needs.detect-languages.outputs.auto-prerelease }}
files: |
Expand Down Expand Up @@ -818,7 +866,7 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
FULL_VERSION: ${{ needs.detect-languages.outputs.full-version }}
RC_TAG: ${{ steps.version.outputs.version }}
CHANGELOG: ${{ steps.changelog.outputs.changelog_content }}
CHANGELOG_FILE: ${{ steps.changelog.outputs.changelog_file || steps.legacy-notes.outputs.changelog_file }}
run: |
set -euo pipefail

Expand Down Expand Up @@ -848,22 +896,28 @@ jobs:
'[.[] | select(.tagName == $v) | .id] | .[]')
EXISTING_ID=${MATCHING_IDS%%$'\n'*}

NOTES=$(cat <<NOTES_EOF
Draft release for $FULL_VERSION — will be published when ready.

Latest RC: $RC_TAG

$CHANGELOG
NOTES_EOF
)
# Notes go through a file (gh api -F body=@file, gh release
# --notes-file), never argv: one argv string is capped at 128 KiB
# and a long changelog exceeds it ("Argument list too long").
if [ ! -s "${CHANGELOG_FILE:-}" ]; then
echo "::error::No non-empty release notes file (changelog_file, or the legacy changelog_content). Check the Generate changelog step; if the ghcommon scripts ref is old, set .github/ghcommon-ref.txt to a current github-common SHA."
exit 1
fi
NOTES_FILE="${RUNNER_TEMP}/release-notes/draft-body.md"
mkdir -p "$(dirname "$NOTES_FILE")"
{
printf 'Draft release for %s — will be published when ready.\n\n' "$FULL_VERSION"
printf 'Latest RC: %s\n\n' "$RC_TAG"
cat "$CHANGELOG_FILE"
} > "$NOTES_FILE"

if [ -n "$EXISTING_ID" ]; then
echo "Updating existing draft release $FULL_VERSION (id=$EXISTING_ID)"
gh api -X PATCH "repos/${GITHUB_REPOSITORY}/releases/${EXISTING_ID}" \
-f tag_name="$FULL_VERSION" \
-f target_commitish="$GITHUB_SHA" \
-f name="$FULL_VERSION" \
-f body="$NOTES" \
-F body=@"$NOTES_FILE" \
-F draft=true >/dev/null

# Any further drafts on this same version are duplicates minted by
Expand All @@ -879,7 +933,7 @@ jobs:
gh release create "$FULL_VERSION" \
--target "$GITHUB_SHA" \
--title "$FULL_VERSION" \
--notes "$NOTES" \
--notes-file "$NOTES_FILE" \
--draft
fi

Expand Down
Loading
Loading