Add Snap Store packaging

Publish OrcaSlicer to the Snap Store (classic confinement) on channels
matching the release tiers: stable / candidate / beta / edge. The Linux
build (both arches) repackages the AppImage AppDir into a snap; nightly
builds go to edge, and tagged releases publish to the matching channel.

Stacked on the Linux ARM64 AppImage change.
This commit is contained in:
SoftFever
2026-06-19 14:14:20 +08:00
parent 0a6a42ecb5
commit 617df79260
7 changed files with 275 additions and 3 deletions

View File

@@ -14,6 +14,7 @@ on:
- 'resources/**'
- ".github/workflows/build_*.yml"
- 'scripts/flatpak/**'
- 'snap/**'
- 'scripts/msix/**'
- 'tests/**'
@@ -32,6 +33,7 @@ on:
- 'build_release_vs2022.bat'
- 'build_release_macos.sh'
- 'scripts/flatpak/**'
- 'snap/**'
- 'scripts/msix/**'
- 'tests/**'
@@ -56,7 +58,7 @@ jobs:
strategy:
fail-fast: false
# Build both arches on every event (PRs included), through the same
# build_check_cache -> build_deps -> build_orca chain (the AppImage).
# build_check_cache -> build_deps -> build_orca chain (AppImage + snap).
# aarch64 always uses the GitHub-hosted arm runner (there is no arm
# self-hosted server). amd64's empty arch is load-bearing: it keeps the
# historical 'linux-clang' deps cache key and the unsuffixed asset names.

View File

@@ -65,10 +65,14 @@ jobs:
echo "ver_pure=$ver_pure" >> $GITHUB_ENV
echo "date=$(date +'%Y%m%d')" >> $GITHUB_ENV
echo "git_commit_hash=$git_commit_hash" >> $GITHUB_ENV
# Per-arch Linux AppImage naming: amd64 keeps the historical unsuffixed
# name (arch_suffix empty). Unused on macOS/Windows.
# Per-arch Linux naming, computed once: amd64 keeps the historical
# unsuffixed names (arch_suffix empty); snap_arch is snapcraft's token.
# Unused on macOS/Windows.
if [ '${{ inputs.arch }}' = 'aarch64' ]; then
echo "arch_suffix=_aarch64" >> $GITHUB_ENV
echo "snap_arch=arm64" >> $GITHUB_ENV
else
echo "snap_arch=amd64" >> $GITHUB_ENV
fi
shell: bash
@@ -419,6 +423,37 @@ jobs:
chmod +x "$appimage"
if $tests; then tar -cvpf build_tests.tar build/tests; fi
# Build the snap right here, reusing the AppDir we just produced
# (build/package): the compiled binary + bundled libs + resources are
# repackaged as-is, for both amd64 and aarch64. Skipped on PRs (snapcraft
# adds several minutes per arch). The snap is Store-only; it is never
# attached to a GitHub release.
- name: Free disk space for snap build
if: runner.os == 'Linux' && !vars.SELF_HOSTED && github.event_name != 'pull_request'
run: sudo rm -rf /usr/local/lib/android /usr/share/dotnet /opt/ghc /opt/hostedtoolcache || true
- name: Build snap
if: runner.os == 'Linux' && !vars.SELF_HOSTED && github.event_name != 'pull_request'
id: snapbuild
uses: snapcore/action-build@v1
- name: Upload snap artifact
if: ${{ ! env.ACT && runner.os == 'Linux' && !vars.SELF_HOSTED && github.event_name != 'pull_request' }}
uses: actions/upload-artifact@v7
with:
name: OrcaSlicer-Linux-snap_${{ env.ver }}_${{ env.snap_arch }}.snap
path: ${{ steps.snapbuild.outputs.snap }}
retention-days: 5
if-no-files-found: error
# Nightly -> Snap Store 'edge'. NOTE: classic confinement means the Store
# holds uploads for manual review until classic is granted (snap/README.md).
- name: Publish snap to edge (nightly)
if: github.repository == 'OrcaSlicer/OrcaSlicer' && github.ref == 'refs/heads/main' && runner.os == 'Linux' && !vars.SELF_HOSTED
uses: snapcore/action-publish@v1
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }}
with:
snap: ${{ steps.snapbuild.outputs.snap }}
release: edge
# Use tar because upload-artifacts won't always preserve directory structure
# and doesn't preserve file permissions
- name: Upload Test Artifact

View File

@@ -79,6 +79,7 @@ jobs:
-p 'OrcaSlicer_Mac_universal_*' \
-p 'OrcaSlicer_Linux_ubuntu_*' \
-p 'OrcaSlicer-Linux-flatpak_*' \
-p 'OrcaSlicer-Linux-snap_*' \
-p 'PDB'
echo "Downloaded artifact folders:"
ls -1 artifacts
@@ -101,6 +102,9 @@ jobs:
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/ \;
# Snaps are intentionally NOT copied here: they go to the Snap Store
# only (see the "Publish snaps to the Snap Store" step), not to the
# GitHub release.
# Windows debug symbols (PDB archive, for developers).
find artifacts -type f -name 'Debug_PDB_*.7z' -exec cp -v {} upload/ \;
@@ -126,3 +130,30 @@ jobs:
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'
- name: Publish snaps to the Snap Store
# Snaps ship to the Store only (not as release assets). Channel comes from
# the tag suffix; nightly -> edge is handled in the build workflows.
# NOTE: classic confinement means the Store holds uploads for manual
# review until classic is granted (see snap/README.md).
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }}
run: |
set -euo pipefail
mapfile -t snaps < <(find artifacts -type f -name '*.snap')
if [ ${#snaps[@]} -eq 0 ]; then
echo "::warning::No .snap artifacts in run $RUN_ID; skipping Snap Store publish."
exit 0
fi
case "$TAG" in
*-rc*) channel=candidate ;;
*-beta*|*-alpha*) channel=beta ;;
*) channel=stable ;;
esac
echo "Releasing $TAG to Snap Store channel: $channel"
sudo snap install snapcraft --classic
for s in "${snaps[@]}"; do
echo "::group::snapcraft upload $s --release=$channel"
snapcraft upload "$s" --release="$channel"
echo "::endgroup::"
done