Skip to content

fix(ci): let publish workflow own release publication (#76) #13

fix(ci): let publish workflow own release publication (#76)

fix(ci): let publish workflow own release publication (#76) #13

name: Release Drafter
on:
push:
branches:
- master
workflow_dispatch: {}
permissions:
contents: read
jobs:
update_release_draft:
permissions:
contents: write
pull-requests: write
runs-on: blacksmith-2vcpu-ubuntu-2404
steps:
- name: Checkout Repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- name: Install oasdiff
env:
OASDIFF_VERSION: 1.28.0
run: |
curl -fsSL -o /tmp/oasdiff.tar.gz \
"https://github.com/oasdiff/oasdiff/releases/download/v${OASDIFF_VERSION}/oasdiff_${OASDIFF_VERSION}_linux_amd64.tar.gz"
tar -xzf /tmp/oasdiff.tar.gz -C /usr/local/bin oasdiff
- name: Generate OpenAPI diff since last release
run: |
LATEST_TAG=$(git tag -l 'v*' --sort=-v:refname | grep -v "^${GITHUB_REF_NAME}$" | head -1)
if [ -n "$LATEST_TAG" ] && git show "${LATEST_TAG}:api/openapi.yaml" > /tmp/base-openapi.yaml 2>/dev/null; then
CHANGELOG=$(oasdiff changelog --format markdown /tmp/base-openapi.yaml api/openapi.yaml || true)
if [ -z "$CHANGELOG" ] || echo "$CHANGELOG" | grep -q "No changes detected"; then
SUMMARY="_No API changes detected._"
echo "OPENAPI_HAS_CHANGES=false" >> "$GITHUB_ENV"
else
CHANGE_COUNT=$(echo "$CHANGELOG" | grep -c '^- ' || echo 0)
BREAKING_OUTPUT=$(oasdiff breaking --format text /tmp/base-openapi.yaml api/openapi.yaml 2>/dev/null || true)
BREAKING_COUNT=$(echo "$BREAKING_OUTPUT" | grep -c '^error' || echo 0)
WARNING_COUNT=$(echo "$BREAKING_OUTPUT" | grep -c '^warning' || echo 0)
COUNTS="${CHANGE_COUNT} API change(s)"
if [ "$BREAKING_COUNT" -gt 0 ] && [ "$WARNING_COUNT" -gt 0 ]; then
COUNTS="${COUNTS} (${BREAKING_COUNT} breaking, ${WARNING_COUNT} potentially breaking)"
elif [ "$BREAKING_COUNT" -gt 0 ]; then
COUNTS="${COUNTS} (${BREAKING_COUNT} breaking)"
elif [ "$WARNING_COUNT" -gt 0 ]; then
COUNTS="${COUNTS} (${WARNING_COUNT} potentially breaking)"
fi
SUMMARY="This release includes ${COUNTS}, via [\`oasdiff\`](https://github.com/oasdiff/oasdiff). The full changelog [can be found attached to this release](<!-- ASSET_URL -->)."
if [ "$BREAKING_COUNT" -gt 0 ] || [ "$WARNING_COUNT" -gt 0 ]; then
BREAKING_MD=$(oasdiff breaking --format markdown /tmp/base-openapi.yaml api/openapi.yaml 2>/dev/null || true)
SUMMARY=$(printf '%s\n\n<details>\n<summary>Breaking and potentially breaking changes</summary>\n\n%s\n\n</details>' "$SUMMARY" "$BREAKING_MD")
fi
echo "OPENAPI_HAS_CHANGES=true" >> "$GITHUB_ENV"
fi
elif [ -n "$LATEST_TAG" ]; then
SUMMARY="_No OpenAPI spec found for tag \`${LATEST_TAG}\`._"
echo "OPENAPI_HAS_CHANGES=false" >> "$GITHUB_ENV"
else
SUMMARY="_No previous release tag found._"
echo "OPENAPI_HAS_CHANGES=false" >> "$GITHUB_ENV"
fi
echo "$SUMMARY" > /tmp/openapi-summary.txt
echo "${CHANGELOG:-}" > /tmp/openapi-diff.md
- id: release_drafter
uses: release-drafter/release-drafter@72967cdc98ddd3160f1fc3dff619de365e137dd0 # v7.9.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Inject OpenAPI diff into release body
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const fs = require('fs');
const releaseId = ${{ steps.release_drafter.outputs.id }};
const hasChanges = '${{ env.OPENAPI_HAS_CHANGES }}' === 'true';
const summary = fs.readFileSync('/tmp/openapi-summary.txt', 'utf8').trim();
let inlineContent = summary;
if (hasChanges) {
const { data: assets } = await github.rest.repos.listReleaseAssets({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: releaseId,
});
const existing = assets.find(a => a.name === 'openapi-diff.md');
if (existing) {
await github.rest.repos.deleteReleaseAsset({
owner: context.repo.owner,
repo: context.repo.repo,
asset_id: existing.id,
});
}
const diff = fs.readFileSync('/tmp/openapi-diff.md', 'utf8');
const { data: asset } = await github.rest.repos.uploadReleaseAsset({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: releaseId,
name: 'openapi-diff.md',
data: diff,
});
inlineContent = summary.replace('<!-- ASSET_URL -->', asset.browser_download_url);
}
const { data: release } = await github.rest.repos.getRelease({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: releaseId,
});
const bodyLimit = 125000;
let newBody = release.body.replace('<!-- OPENAPI_DIFF -->', inlineContent);
if (newBody.length > bodyLimit) {
const fallback = inlineContent.replace(/<details>[\s\S]*<\/details>/, '_Breaking and potentially breaking changes omitted — see attached `openapi-diff.md` for details._');
newBody = release.body.replace('<!-- OPENAPI_DIFF -->', fallback);
}
await github.rest.repos.updateRelease({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: releaseId,
body: newBody,
});