ci(snap): build from shared Linux payload
This commit is contained in:
parent
679c471c61
commit
2d9b828b87
3 changed files with 113 additions and 192 deletions
80
.github/workflows/release.yml
vendored
80
.github/workflows/release.yml
vendored
|
|
@ -43,6 +43,17 @@ jobs:
|
||||||
rsvg-convert -w 256 -h 256 assets/logo.svg \
|
rsvg-convert -w 256 -h 256 assets/logo.svg \
|
||||||
-o AppDir/usr/share/icons/hicolor/256x256/apps/io.github.HakanSeven12.OpenCadStudio.png
|
-o AppDir/usr/share/icons/hicolor/256x256/apps/io.github.HakanSeven12.OpenCadStudio.png
|
||||||
|
|
||||||
|
- name: Pack shared Linux payload
|
||||||
|
run: tar -C AppDir -czf linux-payload.tar.gz usr
|
||||||
|
|
||||||
|
- name: Upload shared Linux payload
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: linux-payload
|
||||||
|
path: linux-payload.tar.gz
|
||||||
|
if-no-files-found: error
|
||||||
|
retention-days: 7
|
||||||
|
|
||||||
- name: Download linuxdeploy
|
- name: Download linuxdeploy
|
||||||
run: |
|
run: |
|
||||||
wget -q https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
|
wget -q https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
|
||||||
|
|
@ -68,6 +79,75 @@ jobs:
|
||||||
mv OpenCADStudio.AppImage "$ASSET"
|
mv OpenCADStudio.AppImage "$ASSET"
|
||||||
gh release upload ${{ github.ref_name }} "$ASSET" --clobber --repo ${{ github.repository }}
|
gh release upload ${{ github.ref_name }} "$ASSET" --clobber --repo ${{ github.repository }}
|
||||||
|
|
||||||
|
build-snap:
|
||||||
|
needs: build-appimage
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
timeout-minutes: 75
|
||||||
|
concurrency:
|
||||||
|
group: snap
|
||||||
|
cancel-in-progress: false
|
||||||
|
permissions:
|
||||||
|
actions: read
|
||||||
|
contents: write
|
||||||
|
env:
|
||||||
|
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Download shared Linux payload
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: linux-payload
|
||||||
|
path: .
|
||||||
|
|
||||||
|
- name: Set package version
|
||||||
|
env:
|
||||||
|
EVENT_NAME: ${{ github.event_name }}
|
||||||
|
REF_NAME: ${{ github.ref_name }}
|
||||||
|
run: |
|
||||||
|
if [ "$EVENT_NAME" = "release" ]; then
|
||||||
|
VERSION="${REF_NAME#v}"
|
||||||
|
if [ "v$VERSION" != "$REF_NAME" ]; then
|
||||||
|
echo "::error::Release tag must be vX.Y.Z"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
VERSION="$(sed -n 's/^version = "\([0-9][0-9.]*\)"/\1/p' Cargo.toml | head -1)"
|
||||||
|
fi
|
||||||
|
if ! printf '%s' "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
|
||||||
|
echo "::error::Invalid package version: $VERSION"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
sed -i "s/^version: .*/version: '$VERSION'/" snap/snapcraft.yaml
|
||||||
|
|
||||||
|
- name: Build snap
|
||||||
|
id: snapcraft
|
||||||
|
uses: snapcore/action-build@v1
|
||||||
|
|
||||||
|
- name: Upload snap to release
|
||||||
|
if: github.event_name == 'release'
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
SNAP: ${{ steps.snapcraft.outputs.snap }}
|
||||||
|
run: gh release upload "${{ github.ref_name }}" "$SNAP" --clobber
|
||||||
|
|
||||||
|
- name: Upload snap as workflow artifact
|
||||||
|
if: github.event_name == 'workflow_dispatch'
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: open-cad-studio-snap
|
||||||
|
path: ${{ steps.snapcraft.outputs.snap }}
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
|
- name: Publish snap to edge
|
||||||
|
if: github.event_name == 'release' && env.SNAPCRAFT_STORE_CREDENTIALS != ''
|
||||||
|
uses: snapcore/action-publish@v1
|
||||||
|
with:
|
||||||
|
snap: ${{ steps.snapcraft.outputs.snap }}
|
||||||
|
release: edge
|
||||||
|
|
||||||
build-windows:
|
build-windows:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
permissions:
|
permissions:
|
||||||
|
|
|
||||||
169
.github/workflows/snap.yml
vendored
169
.github/workflows/snap.yml
vendored
|
|
@ -1,169 +0,0 @@
|
||||||
name: Build Snap Package
|
|
||||||
|
|
||||||
on:
|
|
||||||
# workflow_run only works if this workflow file lives on the DEFAULT branch.
|
|
||||||
# Triggered as soon as "Release" finishes (which itself triggers on
|
|
||||||
# `release: published` + workflow_dispatch, not on every push to main).
|
|
||||||
workflow_run:
|
|
||||||
workflows: ["Release"]
|
|
||||||
types: [completed]
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
version:
|
|
||||||
description: 'Existing release tag to build against (test)'
|
|
||||||
required: true
|
|
||||||
default: 'v0.9.0'
|
|
||||||
|
|
||||||
# Minimal default; the build-snap job raises this to `contents: write` itself,
|
|
||||||
# because it attaches the snap as a release asset.
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
# One global group, and deliberately NOT cancel-in-progress: two releases in
|
|
||||||
# quick succession would both publish to the Snap Store's `stable` channel, and
|
|
||||||
# a Snap release cannot be retracted.
|
|
||||||
concurrency:
|
|
||||||
group: snap
|
|
||||||
cancel-in-progress: false
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-snap:
|
|
||||||
timeout-minutes: 75
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
# `types: [completed]` also fires when the release workflow FAILED or was
|
|
||||||
# cancelled; without this gate a failed release would still build a snap.
|
|
||||||
# No extra head_branch guard is needed here: "Release" only triggers on
|
|
||||||
# `release: published` + workflow_dispatch, never on an ordinary push to
|
|
||||||
# main, so there is no spurious-trigger scenario.
|
|
||||||
if: github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success'
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
env:
|
|
||||||
# Job-level so the gated publish step can reference it from `if:`.
|
|
||||||
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v5
|
|
||||||
with:
|
|
||||||
# On workflow_run, checkout defaults to the DEFAULT BRANCH rather than
|
|
||||||
# the tag/commit the release workflow built — wrong, because
|
|
||||||
# snap/snapcraft.yaml must come from the built commit. Hence the
|
|
||||||
# explicit head_sha of that workflow; for workflow_dispatch (no
|
|
||||||
# workflow_run event) it falls back to github.ref, i.e. the branch the
|
|
||||||
# manual dispatch was started from.
|
|
||||||
ref: ${{ github.event.workflow_run.head_sha || github.ref }}
|
|
||||||
|
|
||||||
- name: Get version
|
|
||||||
id: get-version
|
|
||||||
env:
|
|
||||||
# Untrusted input goes through env, NEVER directly as ${} in the shell.
|
|
||||||
# Do not set GITHUB_* names here: they are reserved and already present.
|
|
||||||
EVENT_NAME: ${{ github.event_name }}
|
|
||||||
DISPATCH_VERSION: ${{ github.event.inputs.version }}
|
|
||||||
HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
|
|
||||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
run: |
|
|
||||||
if [ "$EVENT_NAME" = "workflow_dispatch" ]; then
|
|
||||||
VERSION="$DISPATCH_VERSION"
|
|
||||||
elif [ "$EVENT_NAME" = "workflow_run" ]; then
|
|
||||||
# For a `release`-triggered workflow_run, head_branch is not
|
|
||||||
# guaranteed to be the tag name (it can be the default branch), so
|
|
||||||
# fall back to looking up the latest published release instead of
|
|
||||||
# trusting head_branch.
|
|
||||||
if printf '%s' "$HEAD_BRANCH" | grep -qE '^v[0-9]'; then
|
|
||||||
VERSION="$HEAD_BRANCH"
|
|
||||||
else
|
|
||||||
VERSION="$(gh release list --exclude-drafts --limit 1 --json tagName --jq '.[0].tagName // empty')"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
VERSION=""
|
|
||||||
fi
|
|
||||||
if [ -z "$VERSION" ]; then
|
|
||||||
echo "::error::Could not determine version (event=$EVENT_NAME, head_branch=$HEAD_BRANCH)"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
# `version` and `version_number` are fed into a `sed` REPLACEMENT
|
|
||||||
# PATTERN below, and a dispatch input is free text — a '/' or '&' would
|
|
||||||
# rewrite that pattern, and a newline would write a second line into
|
|
||||||
# $GITHUB_OUTPUT (output injection). Whitelist: the `case` covers the
|
|
||||||
# entire value (including newlines), the regex then checks structure.
|
|
||||||
case "$VERSION" in
|
|
||||||
*[!v0-9.]*)
|
|
||||||
echo "::error::Version contains characters other than 'v', digits and dots." >&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
if ! printf '%s' "$VERSION" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$'; then
|
|
||||||
echo "::error::Version '$VERSION' is not of the form vX.Y.Z." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
|
||||||
echo "version_number=${VERSION#v}" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
# We do NOT rebuild the Rust app: the snap repackages the AppImage from the
|
|
||||||
# published GitHub release (--appimage-extract rather than dpkg-deb -x,
|
|
||||||
# since this project does not produce a .deb).
|
|
||||||
- name: Wait for release AppImage and download it
|
|
||||||
env:
|
|
||||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
VERSION: ${{ steps.get-version.outputs.version }}
|
|
||||||
run: |
|
|
||||||
echo "Waiting for AppImage asset of release $VERSION..."
|
|
||||||
found=""
|
|
||||||
for i in $(seq 1 10); do
|
|
||||||
if gh release view "$VERSION" --json assets --jq '.assets[].name' 2>/dev/null | grep -q '\.AppImage$'; then
|
|
||||||
found=1
|
|
||||||
echo "AppImage asset found"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
echo "no AppImage asset yet... (attempt $i/10)"
|
|
||||||
sleep 15
|
|
||||||
done
|
|
||||||
if [ -z "$found" ]; then
|
|
||||||
echo "::error::AppImage asset for $VERSION did not appear in time"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
gh release download "$VERSION" -p '*.AppImage' --clobber --dir .
|
|
||||||
appimage=$(ls *.AppImage | head -1)
|
|
||||||
cp "$appimage" open-cad-studio.AppImage
|
|
||||||
echo "Using $appimage -> open-cad-studio.AppImage"
|
|
||||||
|
|
||||||
- name: Set version in snapcraft.yaml
|
|
||||||
env:
|
|
||||||
VERSION_NUMBER: ${{ steps.get-version.outputs.version_number }}
|
|
||||||
run: |
|
|
||||||
sed -i "s/^version: .*/version: '$VERSION_NUMBER'/" snap/snapcraft.yaml
|
|
||||||
grep '^version:' snap/snapcraft.yaml
|
|
||||||
|
|
||||||
- name: Build snap
|
|
||||||
uses: snapcore/action-build@v1
|
|
||||||
id: snapcraft
|
|
||||||
|
|
||||||
# Real release (via workflow_run): attach the snap as a release asset.
|
|
||||||
- name: Upload snap to GitHub release
|
|
||||||
if: github.event_name == 'workflow_run'
|
|
||||||
env:
|
|
||||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
VERSION: ${{ steps.get-version.outputs.version }}
|
|
||||||
SNAP: ${{ steps.snapcraft.outputs.snap }}
|
|
||||||
run: |
|
|
||||||
gh release upload "$VERSION" "$SNAP" --clobber
|
|
||||||
|
|
||||||
# Manual test run: snap as a CI artifact only, do NOT touch the release.
|
|
||||||
- name: Upload snap as workflow artifact
|
|
||||||
if: github.event_name == 'workflow_dispatch'
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: open-cad-studio-snap
|
|
||||||
path: ${{ steps.snapcraft.outputs.snap }}
|
|
||||||
if-no-files-found: error
|
|
||||||
|
|
||||||
# Publishing live to the Snap Store: only on a real release, and only once
|
|
||||||
# the store credentials secret exists (an owner step) — and only once the
|
|
||||||
# name `open-cad-studio` has been registered on snapcraft.io.
|
|
||||||
- name: Publish to Snap Store
|
|
||||||
if: github.event_name == 'workflow_run' && env.SNAPCRAFT_STORE_CREDENTIALS != ''
|
|
||||||
uses: snapcore/action-publish@v1
|
|
||||||
with:
|
|
||||||
snap: ${{ steps.snapcraft.outputs.snap }}
|
|
||||||
release: stable
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
name: open-cad-studio
|
name: open-cad-studio
|
||||||
base: core22
|
base: core22
|
||||||
# Overwritten in CI with the release version number (see .github/workflows/snap.yml).
|
# Overwritten in CI with the release version number (see .github/workflows/release.yml).
|
||||||
version: '0.0.0'
|
version: '0.0.0'
|
||||||
title: Open CAD Studio
|
title: Open CAD Studio
|
||||||
summary: 2D drafting and 3D modeling with native DWG/DXF support
|
summary: 2D drafting and 3D modeling with native DWG/DXF support
|
||||||
|
|
@ -35,15 +35,34 @@ description: |
|
||||||
grade: stable
|
grade: stable
|
||||||
confinement: strict
|
confinement: strict
|
||||||
|
|
||||||
|
plugs:
|
||||||
|
graphics-core22:
|
||||||
|
interface: content
|
||||||
|
target: $SNAP/graphics
|
||||||
|
default-provider: mesa-core22
|
||||||
|
|
||||||
|
layout:
|
||||||
|
/usr/share/libdrm:
|
||||||
|
bind: $SNAP/graphics/libdrm
|
||||||
|
/usr/share/drirc.d:
|
||||||
|
symlink: $SNAP/graphics/drirc.d
|
||||||
|
/usr/share/X11/XErrorDB:
|
||||||
|
symlink: $SNAP/graphics/X11/XErrorDB
|
||||||
|
/usr/share/X11/locale:
|
||||||
|
symlink: $SNAP/graphics/X11/locale
|
||||||
|
|
||||||
apps:
|
apps:
|
||||||
open-cad-studio:
|
open-cad-studio:
|
||||||
|
command-chain:
|
||||||
|
- bin/graphics-core22-wrapper
|
||||||
command: usr/bin/OpenCADStudio
|
command: usr/bin/OpenCADStudio
|
||||||
desktop: usr/share/applications/io.github.HakanSeven12.OpenCadStudio.desktop
|
desktop: usr/share/applications/io.github.HakanSeven12.OpenCadStudio.desktop
|
||||||
plugs:
|
plugs:
|
||||||
- home # open/save/export drawings in the home directory
|
- home # open/save/export drawings in the home directory
|
||||||
- removable-media # same, on external drives / USB
|
- removable-media # same, on external drives / USB
|
||||||
- network # license / Patreon check
|
- network # license / Patreon check
|
||||||
- opengl # GPU access for wgpu (Vulkan/GL)
|
- opengl
|
||||||
|
- graphics-core22
|
||||||
- wayland
|
- wayland
|
||||||
- x11
|
- x11
|
||||||
- desktop
|
- desktop
|
||||||
|
|
@ -51,33 +70,24 @@ apps:
|
||||||
|
|
||||||
parts:
|
parts:
|
||||||
open-cad-studio:
|
open-cad-studio:
|
||||||
plugin: nil
|
plugin: dump
|
||||||
# The CI step copies the published release AppImage to the project root as
|
source: linux-payload.tar.gz
|
||||||
# `open-cad-studio.AppImage`; we unpack that instead of rebuilding from
|
|
||||||
# source. `--appimage-extract` yields a ready-made AppDir.
|
|
||||||
override-build: |
|
|
||||||
set -eu
|
|
||||||
chmod +x "${CRAFT_PROJECT_DIR}/open-cad-studio.AppImage"
|
|
||||||
"${CRAFT_PROJECT_DIR}/open-cad-studio.AppImage" --appimage-extract
|
|
||||||
mkdir -p "${CRAFT_PART_INSTALL}/usr"
|
|
||||||
cp -r squashfs-root/usr/. "${CRAFT_PART_INSTALL}/usr/"
|
|
||||||
# OCS uses winit (X11/Wayland) + wgpu (Vulkan with a GL fallback), not
|
|
||||||
# GTK/WebKit — so deliberately NO `extensions: [gnome]`.
|
|
||||||
# libvulkan1/mesa-vulkan-drivers are a fallback; real hardware acceleration
|
|
||||||
# goes through the `opengl` plug to the host driver.
|
|
||||||
stage-packages:
|
stage-packages:
|
||||||
- libvulkan1
|
|
||||||
- mesa-vulkan-drivers
|
|
||||||
- libgl1
|
|
||||||
- libx11-6
|
|
||||||
- libxcursor1
|
- libxcursor1
|
||||||
- libxi6
|
- libxi6
|
||||||
- libxrandr2
|
- libxrandr2
|
||||||
- libxinerama1
|
- libxinerama1
|
||||||
- libxkbcommon0
|
- libxkbcommon0
|
||||||
- libxkbcommon-x11-0
|
- libxkbcommon-x11-0
|
||||||
- libwayland-client0
|
|
||||||
- libwayland-cursor0
|
|
||||||
- libwayland-egl1
|
|
||||||
- libfontconfig1
|
- libfontconfig1
|
||||||
- libfreetype6
|
- libfreetype6
|
||||||
|
|
||||||
|
graphics-core22:
|
||||||
|
after: [open-cad-studio]
|
||||||
|
source: https://github.com/canonical/gpu-snap.git
|
||||||
|
plugin: dump
|
||||||
|
override-prime: |
|
||||||
|
craftctl default
|
||||||
|
${CRAFT_PART_SRC}/bin/graphics-core22-cleanup mesa-core22 nvidia-core22
|
||||||
|
prime:
|
||||||
|
- bin/graphics-core22-wrapper
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue