* fix: modrinth hosting changelog in app changelog for github releases * chore: changelog
223 lines
10 KiB
YAML
223 lines
10 KiB
YAML
name: Modrinth App release
|
|
on:
|
|
workflow_run:
|
|
workflows: ['Modrinth App build']
|
|
types: [completed]
|
|
|
|
jobs:
|
|
release:
|
|
name: Release Modrinth App
|
|
if: >-
|
|
github.event.workflow_run.conclusion == 'success' &&
|
|
github.event.workflow_run.event == 'push' &&
|
|
startsWith(github.event.workflow_run.head_branch, 'v')
|
|
runs-on: ubuntu-latest
|
|
|
|
env:
|
|
VERSION_TAG: ${{ github.event.workflow_run.head_branch }}
|
|
LINUX_X64_BUNDLE_ARTIFACT_NAME: App bundle (x86_64-unknown-linux-gnu)
|
|
WINDOWS_X64_BUNDLE_ARTIFACT_NAME: App bundle (x86_64-pc-windows-msvc)
|
|
MACOS_UNIVERSAL_BUNDLE_ARTIFACT_NAME: App bundle (universal-apple-darwin)
|
|
LAUNCHER_FILES_BUCKET_BASE_URL: https://launcher-files.modrinth.com
|
|
|
|
steps:
|
|
- name: 📥 Check out code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: 🔒 Verify ref is a tag
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
|
|
run: |
|
|
tag_sha=$(gh api "repos/${{ github.repository }}/git/refs/tags/${VERSION_TAG}" --jq '.object.sha' 2>/dev/null || true)
|
|
if [ -z "$tag_sha" ]; then
|
|
echo "::error::${VERSION_TAG} is not a git tag in this repo"
|
|
exit 1
|
|
fi
|
|
if [ "$tag_sha" != "$HEAD_SHA" ]; then
|
|
commit_sha=$(gh api "repos/${{ github.repository }}/git/tags/${tag_sha}" --jq '.object.sha' 2>/dev/null || echo "$tag_sha")
|
|
if [ "$commit_sha" != "$HEAD_SHA" ]; then
|
|
echo "::error::Tag ${VERSION_TAG} (${commit_sha}) does not match build head_sha (${HEAD_SHA})"
|
|
exit 1
|
|
fi
|
|
fi
|
|
echo "Verified ${VERSION_TAG} is a tag pointing at ${HEAD_SHA}"
|
|
|
|
- name: 📥 Download Modrinth App artifacts
|
|
uses: dawidd6/action-download-artifact@v11
|
|
with:
|
|
workflow: theseus-build.yml
|
|
workflow_conclusion: success
|
|
event: push
|
|
branch: ${{ env.VERSION_TAG }}
|
|
use_unzip: true
|
|
|
|
- name: 📝 Extract app changelog
|
|
env:
|
|
VERSION: ${{ env.VERSION_TAG }}
|
|
run: |
|
|
node <<'EOF'
|
|
const fs = require('fs');
|
|
const version = process.env.VERSION.replace(/^v/, '');
|
|
const src = fs.readFileSync('packages/blog/changelog.ts', 'utf8');
|
|
|
|
// Parse every entry in the VERSIONS array, preserving their order
|
|
// (which is reverse chronological).
|
|
const entryRe = /\{\s*date:\s*`([^`]+)`,\s*product:\s*'(\w+)',(?:\s*version:\s*[`']([^`']+)[`'],)?\s*body:\s*`([\s\S]*?)`,\s*\}/g;
|
|
const entries = [];
|
|
let match;
|
|
while ((match = entryRe.exec(src)) !== null) {
|
|
entries.push({
|
|
date: match[1],
|
|
product: match[2],
|
|
version: match[3],
|
|
body: match[4],
|
|
});
|
|
}
|
|
|
|
const currentIdx = entries.findIndex(
|
|
(e) => e.product === 'app' && e.version === version,
|
|
);
|
|
if (currentIdx === -1) {
|
|
console.error(`No app changelog entry found for version ${version}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
// Find the surrounding app entries so we can scope hosting changes to
|
|
// exactly what shipped between the previous app release and this one.
|
|
// Entries are in reverse chronological order, so newer entries have
|
|
// smaller indices than older entries.
|
|
let newerAppIdx = -1;
|
|
for (let i = currentIdx - 1; i >= 0; i--) {
|
|
if (entries[i].product === 'app') {
|
|
newerAppIdx = i;
|
|
break;
|
|
}
|
|
}
|
|
let previousAppIdx = entries.length;
|
|
for (let i = currentIdx + 1; i < entries.length; i++) {
|
|
if (entries[i].product === 'app') {
|
|
previousAppIdx = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
const hostingEntries = [];
|
|
for (let i = newerAppIdx + 1; i < previousAppIdx; i++) {
|
|
if (entries[i].product === 'hosting') {
|
|
hostingEntries.push(entries[i]);
|
|
}
|
|
}
|
|
|
|
let output = entries[currentIdx].body;
|
|
if (hostingEntries.length > 0) {
|
|
// Demote any top-level section headings inside hosting bodies so
|
|
// they nest cleanly under the "Modrinth Hosting (included)" header.
|
|
const demoteHeadings = (body) =>
|
|
body.replace(/^(#{1,5})\s/gm, (_, hashes) => `${hashes}# `);
|
|
const hostingBody = hostingEntries
|
|
.map((e) => demoteHeadings(e.body))
|
|
.join('\n\n');
|
|
output += `\n\n---\n\n## Modrinth Hosting (included)\n\n${hostingBody}`;
|
|
}
|
|
|
|
fs.writeFileSync('release-notes.md', output);
|
|
console.log(`Extracted changelog for app ${version}:`);
|
|
console.log(output);
|
|
EOF
|
|
|
|
- name: 🛠️ Generate version manifest
|
|
run: |
|
|
# Reference: https://tauri.app/plugin/updater/#server-support
|
|
jq -nc \
|
|
--arg versionTag "${VERSION_TAG#v}" \
|
|
--rawfile releaseNotes release-notes.md \
|
|
--rawfile macOsAarch64UpdateArtifactSignature "${MACOS_UNIVERSAL_BUNDLE_ARTIFACT_NAME}/universal-apple-darwin/release/bundle/macos/Modrinth App.app.tar.gz.sig" \
|
|
--rawfile macOsX64UpdateArtifactSignature "${MACOS_UNIVERSAL_BUNDLE_ARTIFACT_NAME}/universal-apple-darwin/release/bundle/macos/Modrinth App.app.tar.gz.sig" \
|
|
--rawfile linuxX64UpdateArtifactSignature "${LINUX_X64_BUNDLE_ARTIFACT_NAME}/release/bundle/appimage/Modrinth App_${VERSION_TAG#v}_amd64.AppImage.tar.gz.sig" \
|
|
--rawfile windowsX64UpdateArtifactSignature "${WINDOWS_X64_BUNDLE_ARTIFACT_NAME}/release/bundle/nsis/Modrinth App_${VERSION_TAG#v}_x64-setup.nsis.zip.sig" \
|
|
'{
|
|
"version": $versionTag,
|
|
"notes": $releaseNotes,
|
|
"pub_date": now | todateiso8601,
|
|
"platforms": {
|
|
"darwin-aarch64": {
|
|
"signature": $macOsAarch64UpdateArtifactSignature,
|
|
"url": @uri "${{ env.LAUNCHER_FILES_BUCKET_BASE_URL }}/versions/\($versionTag)/macos/\("Modrinth App.app.tar.gz")",
|
|
"install_urls": [@uri "${{ env.LAUNCHER_FILES_BUCKET_BASE_URL }}/versions/\($versionTag)/macos/\("Modrinth App_" + $versionTag + "_universal.dmg")"]
|
|
},
|
|
"darwin-x86_64": {
|
|
"signature": $macOsX64UpdateArtifactSignature,
|
|
"url": @uri "${{ env.LAUNCHER_FILES_BUCKET_BASE_URL }}/versions/\($versionTag)/macos/\("Modrinth App.app.tar.gz")",
|
|
"install_urls": [@uri "${{ env.LAUNCHER_FILES_BUCKET_BASE_URL }}/versions/\($versionTag)/macos/\("Modrinth App_" + $versionTag + "_universal.dmg")"]
|
|
},
|
|
"linux-x86_64": {
|
|
"signature": $linuxX64UpdateArtifactSignature,
|
|
"url": @uri "${{ env.LAUNCHER_FILES_BUCKET_BASE_URL }}/versions/\($versionTag)/linux/\("Modrinth App_" + $versionTag + "_amd64.AppImage.tar.gz")",
|
|
"install_urls": [
|
|
@uri "${{ env.LAUNCHER_FILES_BUCKET_BASE_URL }}/versions/\($versionTag)/linux/\("Modrinth App_" + $versionTag + "_amd64.deb")",
|
|
@uri "${{ env.LAUNCHER_FILES_BUCKET_BASE_URL }}/versions/\($versionTag)/linux/\("Modrinth App_" + $versionTag + "_amd64.AppImage")",
|
|
@uri "${{ env.LAUNCHER_FILES_BUCKET_BASE_URL }}/versions/\($versionTag)/linux/\("Modrinth App-" + $versionTag + "-1.x86_64.rpm")"
|
|
]
|
|
},
|
|
"windows-x86_64": {
|
|
"signature": $windowsX64UpdateArtifactSignature,
|
|
"url": @uri "${{ env.LAUNCHER_FILES_BUCKET_BASE_URL }}/versions/\($versionTag)/windows/\("Modrinth App_" + $versionTag + "_x64-setup.nsis.zip")",
|
|
"install_urls": [@uri "${{ env.LAUNCHER_FILES_BUCKET_BASE_URL }}/versions/\($versionTag)/windows/\("Modrinth App_" + $versionTag + "_x64-setup.exe")"]
|
|
}
|
|
}
|
|
}' > updates.json
|
|
|
|
echo "Generated manifest for version ${VERSION_TAG}:"
|
|
cat updates.json
|
|
|
|
- name: 📤 Upload release artifacts
|
|
env:
|
|
AWS_ACCESS_KEY_ID: ${{ secrets.LAUNCHER_FILES_BUCKET_ACCESS_KEY_ID }}
|
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.LAUNCHER_FILES_BUCKET_SECRET_ACCESS_KEY }}
|
|
AWS_BUCKET: ${{ secrets.LAUNCHER_FILES_BUCKET_NAME }}
|
|
AWS_REGION: ${{ secrets.LAUNCHER_FILES_BUCKET_REGION }}
|
|
AWS_ENDPOINT_URL: ${{ secrets.LAUNCHER_FILES_BUCKET_ENDPOINT_URL }}
|
|
AWS_PAGER: ''
|
|
# Work around incompatible checksum behavior with some S3-like object storage providers,
|
|
# such as Cloudflare R2. See:
|
|
# - https://developers.cloudflare.com/r2/examples/aws/aws-cli/
|
|
# - https://developers.cloudflare.com/r2/examples/aws/aws-sdk-java/
|
|
AWS_REQUEST_CHECKSUM_CALCULATION: when_required
|
|
AWS_RESPONSE_CHECKSUM_VALIDATION: when_required
|
|
run: |
|
|
for macosBundleType in 'macos' 'dmg'; do
|
|
aws s3 cp --recursive \
|
|
"${MACOS_UNIVERSAL_BUNDLE_ARTIFACT_NAME}/universal-apple-darwin/release/bundle/${macosBundleType}" \
|
|
"s3://${AWS_BUCKET}/versions/${VERSION_TAG#v}/macos"
|
|
done
|
|
|
|
for linuxBundleType in 'appimage' 'deb' 'rpm'; do
|
|
aws s3 cp --recursive \
|
|
"${LINUX_X64_BUNDLE_ARTIFACT_NAME}/release/bundle/${linuxBundleType}" \
|
|
"s3://${AWS_BUCKET}/versions/${VERSION_TAG#v}/linux"
|
|
done
|
|
|
|
for windowsBundleType in 'nsis'; do
|
|
aws s3 cp --recursive \
|
|
"${WINDOWS_X64_BUNDLE_ARTIFACT_NAME}/release/bundle/${windowsBundleType}" \
|
|
"s3://${AWS_BUCKET}/versions/${VERSION_TAG#v}/windows"
|
|
done
|
|
|
|
aws s3 cp updates.json "s3://${AWS_BUCKET}"
|
|
|
|
- name: 🏷️ Create GitHub release
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
run: |
|
|
VERSION="${VERSION_TAG#v}"
|
|
|
|
gh release create "$VERSION_TAG" \
|
|
--title "Modrinth App ${VERSION}" \
|
|
--notes-file release-notes.md \
|
|
"${WINDOWS_X64_BUNDLE_ARTIFACT_NAME}/release/bundle/nsis/Modrinth App_${VERSION}_x64-setup.exe" \
|
|
"${MACOS_UNIVERSAL_BUNDLE_ARTIFACT_NAME}/universal-apple-darwin/release/bundle/dmg/Modrinth App_${VERSION}_universal.dmg" \
|
|
"${LINUX_X64_BUNDLE_ARTIFACT_NAME}/release/bundle/appimage/Modrinth App_${VERSION}_amd64.AppImage" \
|
|
"${LINUX_X64_BUNDLE_ARTIFACT_NAME}/release/bundle/deb/Modrinth App_${VERSION}_amd64.deb" \
|
|
"${LINUX_X64_BUNDLE_ARTIFACT_NAME}/release/bundle/rpm/Modrinth App-${VERSION}-1.x86_64.rpm"
|