fix: finalize repaired releases
This commit is contained in:
@@ -0,0 +1,144 @@
|
|||||||
|
name: Finalize Existing Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
version:
|
||||||
|
description: Existing release version without the v prefix
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
finalize-release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||||
|
DISCORD_UPDATE_ROLE_ID: ${{ secrets.DISCORD_UPDATE_ROLE_ID }}
|
||||||
|
steps:
|
||||||
|
- name: Verify release inventory
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
REPOSITORY: ${{ github.repository }}
|
||||||
|
VERSION: ${{ inputs.version }}
|
||||||
|
run: |
|
||||||
|
node - <<'NODE'
|
||||||
|
(async () => {
|
||||||
|
const { GITHUB_TOKEN: token, REPOSITORY: repo, VERSION: version } = process.env;
|
||||||
|
const expected = [
|
||||||
|
`OpenChamber-${version}-mac-arm64.dmg`,
|
||||||
|
`OpenChamber-${version}-mac-arm64.zip`,
|
||||||
|
`OpenChamber-${version}-mac-x64.dmg`,
|
||||||
|
`OpenChamber-${version}-mac-x64.zip`,
|
||||||
|
`OpenChamber-${version}-win-x64.exe`,
|
||||||
|
'latest-mac.yml',
|
||||||
|
'latest.yml',
|
||||||
|
];
|
||||||
|
const response = await fetch(`https://api.github.com/repos/${repo}/releases/tags/v${version}`, {
|
||||||
|
headers: { Authorization: `Bearer ${token}`, Accept: 'application/vnd.github+json' },
|
||||||
|
});
|
||||||
|
if (!response.ok) throw new Error(`Failed to inspect release: ${response.status} ${await response.text()}`);
|
||||||
|
const release = await response.json();
|
||||||
|
for (const name of expected) {
|
||||||
|
const matches = release.assets.filter((asset) => asset.name === name);
|
||||||
|
if (matches.length !== 1) throw new Error(`Expected exactly one ${name}, found ${matches.length}`);
|
||||||
|
if (!Number.isSafeInteger(matches[0].size) || matches[0].size <= 0) {
|
||||||
|
throw new Error(`Release asset ${name} has invalid size ${matches[0].size}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(`Verified release v${version} inventory before finalization.`);
|
||||||
|
})().catch((error) => {
|
||||||
|
console.error(error);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
NODE
|
||||||
|
|
||||||
|
- name: Publish release
|
||||||
|
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2.6.2
|
||||||
|
with:
|
||||||
|
tag_name: v${{ inputs.version }}
|
||||||
|
draft: false
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Send release to Discord
|
||||||
|
if: ${{ env.DISCORD_WEBHOOK_URL != '' }}
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
VERSION: ${{ inputs.version }}
|
||||||
|
REPOSITORY: ${{ github.repository }}
|
||||||
|
UPDATE_ROLE_ID: ${{ env.DISCORD_UPDATE_ROLE_ID }}
|
||||||
|
run: |
|
||||||
|
node - <<'NODE'
|
||||||
|
(async () => {
|
||||||
|
const tag = `v${process.env.VERSION}`;
|
||||||
|
const repo = process.env.REPOSITORY;
|
||||||
|
const rawRoleId = (process.env.UPDATE_ROLE_ID || '').trim();
|
||||||
|
const updateRoleId = /^\d+$/.test(rawRoleId) ? rawRoleId : '';
|
||||||
|
|
||||||
|
const releaseRes = await fetch(`https://api.github.com/repos/${repo}/releases/tags/${tag}`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
|
||||||
|
Accept: 'application/vnd.github+json',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!releaseRes.ok) {
|
||||||
|
throw new Error(`Failed to fetch release ${tag}: ${releaseRes.status} ${await releaseRes.text()}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const release = await releaseRes.json();
|
||||||
|
const description = (release.body || `OpenChamber ${tag} released.`).slice(0, 4096);
|
||||||
|
const mention = updateRoleId ? `<@&${updateRoleId}>` : '';
|
||||||
|
const payload = {
|
||||||
|
username: 'OpenChamber Releases',
|
||||||
|
...(mention ? { content: mention } : {}),
|
||||||
|
...(updateRoleId ? { allowed_mentions: { roles: [updateRoleId] } } : {}),
|
||||||
|
embeds: [{
|
||||||
|
title: release.name || `OpenChamber ${tag}`,
|
||||||
|
url: release.html_url,
|
||||||
|
description,
|
||||||
|
color: 2105893,
|
||||||
|
footer: { text: 'OpenChamber Changelog' },
|
||||||
|
}],
|
||||||
|
};
|
||||||
|
|
||||||
|
const discordRes = await fetch(process.env.DISCORD_WEBHOOK_URL, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'content-type': 'application/json' },
|
||||||
|
body: JSON.stringify(payload),
|
||||||
|
});
|
||||||
|
if (!discordRes.ok) {
|
||||||
|
throw new Error(`Failed to send Discord release: ${discordRes.status} ${await discordRes.text()}`);
|
||||||
|
}
|
||||||
|
})().catch((error) => {
|
||||||
|
console.error(error);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
NODE
|
||||||
|
|
||||||
|
- name: Trigger openchamber-website site refresh
|
||||||
|
env:
|
||||||
|
WEBSITE_REPO: openchamber/openchamber-website
|
||||||
|
WEBSITE_TOKEN: ${{ secrets.OPENCHAMBER_WEBSITE_REPO_TOKEN }}
|
||||||
|
VERSION: ${{ inputs.version }}
|
||||||
|
run: |
|
||||||
|
if [ -z "$WEBSITE_TOKEN" ]; then
|
||||||
|
echo "OPENCHAMBER_WEBSITE_REPO_TOKEN not set; skip site refresh dispatch."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
curl --fail-with-body -sS -X POST \
|
||||||
|
-H "Authorization: Bearer $WEBSITE_TOKEN" \
|
||||||
|
-H "Accept: application/vnd.github+json" \
|
||||||
|
"https://api.github.com/repos/$WEBSITE_REPO/dispatches" \
|
||||||
|
-d @- <<JSON
|
||||||
|
{
|
||||||
|
"event_type": "site_refresh_requested",
|
||||||
|
"client_payload": {
|
||||||
|
"source_repo": "${{ github.repository }}",
|
||||||
|
"release_tag": "v$VERSION"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSON
|
||||||
Reference in New Issue
Block a user