mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-11-10 08:21:08 +00:00
198 lines
9.2 KiB
YAML
198 lines
9.2 KiB
YAML
name: Publish to draft release
|
|
|
|
# Manually pulls the platform binaries produced by a "Build all" run and uploads
|
|
# them to an existing DRAFT release. Decoupled from the build so you can test a
|
|
# build first, then publish exactly that run's artifacts once you're happy.
|
|
# It also writes an ordered download table into the draft's release notes.
|
|
#
|
|
# Trigger: Actions tab -> "Publish to draft release" -> Run workflow.
|
|
# Locked to a single person: the first step aborts unless the actor matches the
|
|
# `RELEASE_PUBLISHER` repo variable (set to "SoftFever"). To allow someone else,
|
|
# change that variable: gh variable set RELEASE_PUBLISHER --body "<login>".
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
run_id:
|
|
description: 'Run ID of the "Build all" workflow to pull binaries from (the number in the Actions run URL)'
|
|
required: true
|
|
type: string
|
|
tag:
|
|
description: 'Tag of the draft release to upload to (e.g. v2.4.0-beta)'
|
|
required: true
|
|
type: string
|
|
|
|
permissions:
|
|
contents: write # upload release assets
|
|
actions: read # download artifacts from another run
|
|
|
|
jobs:
|
|
publish:
|
|
name: Publish binaries to draft release
|
|
runs-on: ubuntu-latest
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
RUN_ID: ${{ inputs.run_id }}
|
|
TAG: ${{ inputs.tag }}
|
|
steps:
|
|
- name: Restrict to the release publisher
|
|
env:
|
|
PUBLISHER: ${{ vars.RELEASE_PUBLISHER }}
|
|
run: |
|
|
if [ -z "$PUBLISHER" ]; then
|
|
echo "::error::RELEASE_PUBLISHER repo variable is not set."
|
|
exit 1
|
|
fi
|
|
if [ "${{ github.actor }}" != "$PUBLISHER" ]; then
|
|
echo "::error::Only @$PUBLISHER may run this workflow (you are @${{ github.actor }})."
|
|
exit 1
|
|
fi
|
|
echo "Authorized: @${{ github.actor }}"
|
|
|
|
- name: Verify target is a draft release
|
|
run: |
|
|
if ! gh release view "$TAG" --repo "$GITHUB_REPOSITORY" --json isDraft >/dev/null 2>&1; then
|
|
echo "::error::Release '$TAG' not found. Create the draft (with this tag) first."
|
|
exit 1
|
|
fi
|
|
is_draft=$(gh release view "$TAG" --repo "$GITHUB_REPOSITORY" --json isDraft --jq '.isDraft')
|
|
if [ "$is_draft" != "true" ]; then
|
|
echo "::error::Release '$TAG' is published, not a draft. Aborting to avoid touching a live release."
|
|
exit 1
|
|
fi
|
|
|
|
- name: Verify source build run
|
|
run: |
|
|
info=$(gh run view "$RUN_ID" --repo "$GITHUB_REPOSITORY" --json workflowName,conclusion,headBranch)
|
|
name=$(echo "$info" | jq -r '.workflowName')
|
|
conclusion=$(echo "$info" | jq -r '.conclusion')
|
|
branch=$(echo "$info" | jq -r '.headBranch')
|
|
echo "Source run #$RUN_ID: '$name' on '$branch' (conclusion: $conclusion)"
|
|
if [ "$conclusion" != "success" ]; then
|
|
echo "::warning::Source run did not conclude 'success' ($conclusion). Some assets may be missing."
|
|
fi
|
|
|
|
- name: Download release artifacts from build run
|
|
run: |
|
|
# Windows_V* (not Windows_*) keeps the MSIX Store artifact out: it goes to Partner Center, not GitHub releases.
|
|
gh run download "$RUN_ID" --repo "$GITHUB_REPOSITORY" --dir artifacts \
|
|
-p 'OrcaSlicer_Windows_V*' \
|
|
-p 'OrcaSlicer_Mac_universal_*' \
|
|
-p 'OrcaSlicer_Linux_ubuntu_*' \
|
|
-p 'OrcaSlicer-Linux-flatpak_*' \
|
|
-p 'PDB'
|
|
echo "Downloaded artifact folders:"
|
|
ls -1 artifacts
|
|
|
|
- name: Assemble release assets
|
|
run: |
|
|
set -euo pipefail
|
|
mkdir -p upload
|
|
|
|
# gh run download auto-extracts each artifact into a folder, so the inner
|
|
# binaries are already unzipped. Copy the inner binary for each platform.
|
|
# -type f is required (some artifact *folders* are named "*.flatpak").
|
|
|
|
# Windows installers (x64 + arm64): the .exe inside each installer
|
|
# artifact, NOT the orca-slicer.exe in the portable app folder. CPack
|
|
# now bakes the arch into the filename (…_x64.exe / …_arm64.exe), so
|
|
# copy them straight through.
|
|
find artifacts -type f -name '*.exe' -path '*OrcaSlicer_Windows_V*' ! -path '*_portable*' -exec cp -v {} upload/ \;
|
|
# macOS universal DMG (profile-validator DMG isn't downloaded).
|
|
find artifacts -type f -name '*.dmg' -path '*OrcaSlicer_Mac_universal_*' -exec cp -v {} upload/ \;
|
|
# Linux AppImage.
|
|
find artifacts -type f -name '*.AppImage' -exec cp -v {} upload/ \;
|
|
# Flatpak bundles (x86_64 + aarch64).
|
|
find artifacts -type f -name '*.flatpak' -exec cp -v {} upload/ \;
|
|
# Windows debug symbols (PDB archive, for developers).
|
|
find artifacts -type f -name 'Debug_PDB_*.7z' -exec cp -v {} upload/ \;
|
|
|
|
# Portable Windows builds (x64 + arm64) are unzipped folder artifacts;
|
|
# re-zip each to its released filename (these stay .zip on the release).
|
|
mapfile -t portable_dirs < <(find artifacts -maxdepth 1 -type d -name 'OrcaSlicer_Windows_*_portable')
|
|
if [ ${#portable_dirs[@]} -eq 0 ]; then
|
|
echo "::warning::Windows portable artifact not found."
|
|
fi
|
|
for portable_dir in "${portable_dirs[@]}"; do
|
|
( cd "$portable_dir" && zip -qr "$GITHUB_WORKSPACE/upload/$(basename "$portable_dir").zip" . )
|
|
echo "Zipped portable -> $(basename "$portable_dir").zip"
|
|
done
|
|
|
|
echo "Assets to upload:"
|
|
ls -lh upload
|
|
if [ -z "$(ls -A upload)" ]; then
|
|
echo "::error::No assets assembled. Check the run_id and that its artifacts haven't expired."
|
|
exit 1
|
|
fi
|
|
|
|
- name: Upload assets to draft release
|
|
run: |
|
|
gh release upload "$TAG" upload/* --repo "$GITHUB_REPOSITORY" --clobber
|
|
echo "Uploaded to draft release: $TAG"
|
|
gh release view "$TAG" --repo "$GITHUB_REPOSITORY" --json assets --jq '.assets[].name'
|
|
|
|
# GitHub lists release assets alphabetically by filename whatever order they
|
|
# are uploaded in, so the platform order users see comes from this table in
|
|
# the release notes. The table sits between the two markers: a rerun
|
|
# replaces it in place, and notes without markers get it appended. Text
|
|
# outside the markers is kept. Links use the tag's download URL, which only
|
|
# resolves once the draft is published.
|
|
- name: Write download table into release notes
|
|
run: |
|
|
set -euo pipefail
|
|
start='<!-- downloads:start -->'
|
|
end='<!-- downloads:end -->'
|
|
|
|
# Sort key and label of an asset, in the order the table lists them.
|
|
describe() {
|
|
case "$1" in
|
|
*Windows_Installer_*_x64.exe) echo "01|Windows installer (x64)" ;;
|
|
*Windows_Installer_*_arm64.exe) echo "02|Windows installer (ARM64)" ;;
|
|
*_x64_portable.zip) echo "03|Windows portable (x64)" ;;
|
|
*_arm64_portable.zip) echo "04|Windows portable (ARM64)" ;;
|
|
*.dmg) echo "05|macOS (Apple Silicon and Intel)" ;;
|
|
*_aarch64_*.AppImage) echo "07|Linux AppImage (aarch64)" ;;
|
|
*.AppImage) echo "06|Linux AppImage (x86_64)" ;;
|
|
*_x86_64.flatpak) echo "08|Linux Flatpak (x86_64)" ;;
|
|
*_aarch64.flatpak) echo "09|Linux Flatpak (aarch64)" ;;
|
|
Debug_PDB_*) echo "10|Windows debug symbols (for developers)" ;;
|
|
*) echo "99|$1" ;;
|
|
esac
|
|
}
|
|
|
|
{
|
|
echo "$start"
|
|
echo
|
|
echo "## Downloads"
|
|
echo
|
|
echo "| Platform | File |"
|
|
echo "| --- | --- |"
|
|
gh release view "$TAG" --repo "$GITHUB_REPOSITORY" --json assets --jq '.assets[].name' | while read -r name; do
|
|
echo "$(describe "$name")|$name"
|
|
done | sort | while IFS='|' read -r _ label name; do
|
|
echo "| $label | [$name](https://github.com/$GITHUB_REPOSITORY/releases/download/$TAG/$name) |"
|
|
done
|
|
echo
|
|
echo "$end"
|
|
} > table.md
|
|
|
|
gh release view "$TAG" --repo "$GITHUB_REPOSITORY" --json body --jq '.body' > notes.md
|
|
starts=$(grep -cF "$start" notes.md || true)
|
|
ends=$(grep -cF "$end" notes.md || true)
|
|
if [ "$starts" -ne "$ends" ] || [ "$starts" -gt 1 ]; then
|
|
echo "::error::The release notes must contain each download-table marker exactly once, or neither. Fix them by hand and rerun."
|
|
exit 1
|
|
fi
|
|
if [ "$starts" -eq 1 ]; then
|
|
awk -v start="$start" -v end="$end" '
|
|
index($0, start) { while ((getline line < "table.md") > 0) print line; skip = 1; next }
|
|
index($0, end) { skip = 0; next }
|
|
!skip
|
|
END { exit skip }
|
|
' notes.md > notes.new || { echo "::error::The download-table end marker must be on its own line, after the start marker."; exit 1; }
|
|
else
|
|
{ cat notes.md; echo; cat table.md; } > notes.new
|
|
fi
|
|
gh release edit "$TAG" --repo "$GITHUB_REPOSITORY" --notes-file notes.new
|
|
cat table.md
|