mirror of
https://github.com/priyanshujain/margin-calendar.git
synced 2026-10-02 19:17:04 +00:00
No licence file meant nobody had permission to redistribute this, which is a
strange position for a public repo with an AUR package pointing at it. The
PKGBUILD said license=('custom') because there was nothing truthful to put
there.
MIT is not one of the licences Arch keeps in /usr/share/licenses/common, so
the package now fetches the licence from its own tag and installs a copy. The
release workflow checksums that copy from the tag it checked out, rather than
trusting whatever main has drifted to.
Declared in package.json and Cargo.toml too, so the manifests and the package
agree on the answer.
251 lines
9.6 KiB
YAML
251 lines
9.6 KiB
YAML
name: Release
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
version:
|
|
description: "Release version, e.g. 0.2.0. Leave empty to bump the patch number."
|
|
required: false
|
|
type: string
|
|
|
|
permissions:
|
|
contents: write
|
|
|
|
jobs:
|
|
prepare:
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
version: ${{ steps.version.outputs.version }}
|
|
tag: ${{ steps.version.outputs.tag }}
|
|
release_id: ${{ steps.release.outputs.release_id }}
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
|
|
- name: Determine version
|
|
id: version
|
|
run: |
|
|
if [ -n "${{ inputs.version }}" ]; then
|
|
VERSION="${{ inputs.version }}"
|
|
VERSION="${VERSION#v}"
|
|
else
|
|
CURRENT=$(jq -r .version src-tauri/tauri.conf.json)
|
|
IFS=. read -r MAJOR MINOR PATCH <<< "$CURRENT"
|
|
VERSION="$MAJOR.$MINOR.$((PATCH + 1))"
|
|
fi
|
|
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
|
echo "tag=v$VERSION" >> "$GITHUB_OUTPUT"
|
|
echo "Releasing v$VERSION"
|
|
|
|
- name: Bump version in manifests
|
|
env:
|
|
VERSION: ${{ steps.version.outputs.version }}
|
|
run: |
|
|
tmp=$(mktemp)
|
|
jq --arg v "$VERSION" '.version = $v' src-tauri/tauri.conf.json > "$tmp" && mv "$tmp" src-tauri/tauri.conf.json
|
|
jq --arg v "$VERSION" '.version = $v' package.json > "$tmp" && mv "$tmp" package.json
|
|
sed -i "0,/^version = \".*\"/s//version = \"$VERSION\"/" src-tauri/Cargo.toml
|
|
|
|
- name: Commit and tag
|
|
env:
|
|
TAG: ${{ steps.version.outputs.tag }}
|
|
run: |
|
|
git config user.name "github-actions[bot]"
|
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
git add src-tauri/tauri.conf.json package.json src-tauri/Cargo.toml
|
|
git commit -m "chore(release): $TAG"
|
|
for attempt in 1 2 3 4 5; do
|
|
git fetch origin main
|
|
git rebase origin/main
|
|
if git push origin HEAD; then
|
|
break
|
|
fi
|
|
if [ "$attempt" = "5" ]; then
|
|
echo "::error::main kept advancing; could not push release bump after 5 attempts."
|
|
exit 1
|
|
fi
|
|
echo "main advanced during release; rebasing and retrying ($attempt)…"
|
|
sleep 3
|
|
done
|
|
git tag "$TAG"
|
|
git push origin "$TAG"
|
|
|
|
- name: Create draft release
|
|
id: release
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
TAG: ${{ steps.version.outputs.tag }}
|
|
run: |
|
|
gh release create "$TAG" --draft --title "Margin Calendar $TAG" --notes "Release $TAG"
|
|
ID=$(gh release view "$TAG" --json databaseId --jq .databaseId)
|
|
echo "release_id=$ID" >> "$GITHUB_OUTPUT"
|
|
|
|
build:
|
|
needs: prepare
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- os: macos-26
|
|
args: "--target universal-apple-darwin --config src-tauri/tauri.release.conf.json"
|
|
rust-targets: "aarch64-apple-darwin,x86_64-apple-darwin"
|
|
# Ubuntu 22.04 is the glibc baseline docs/setup.md commits to: the bundle will not run on
|
|
# anything older than the glibc it was linked against, so build on the oldest supported.
|
|
- os: ubuntu-22.04
|
|
args: "--config src-tauri/tauri.release.conf.json"
|
|
rust-targets: ""
|
|
runs-on: ${{ matrix.os }}
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.tag }}
|
|
|
|
- name: Install Linux dependencies
|
|
if: startsWith(matrix.os, 'ubuntu')
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y \
|
|
libwebkit2gtk-4.1-dev \
|
|
libgtk-3-dev \
|
|
libayatana-appindicator3-dev \
|
|
librsvg2-dev \
|
|
patchelf \
|
|
libxdo-dev \
|
|
libssl-dev \
|
|
build-essential \
|
|
curl \
|
|
wget \
|
|
file
|
|
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
node-version: 26
|
|
|
|
- uses: pnpm/action-setup@v6
|
|
with:
|
|
version: 10
|
|
|
|
- name: Install Rust
|
|
uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
targets: ${{ matrix.rust-targets }}
|
|
|
|
- uses: swatinem/rust-cache@v2
|
|
with:
|
|
workspaces: src-tauri -> target
|
|
|
|
- name: Install frontend dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
- name: Provision Google credentials
|
|
shell: bash
|
|
env:
|
|
GOOGLE_CREDENTIALS: ${{ secrets.GOOGLE_CREDENTIALS }}
|
|
run: |
|
|
if [ -n "$GOOGLE_CREDENTIALS" ]; then
|
|
printf '%s' "$GOOGLE_CREDENTIALS" > google-credentials.json
|
|
echo "Wrote google-credentials.json from GOOGLE_CREDENTIALS secret."
|
|
else
|
|
cp google-credentials.example.json google-credentials.json
|
|
echo "::warning::GOOGLE_CREDENTIALS secret not set — embedding placeholder credentials; this build cannot connect to Google Calendar."
|
|
fi
|
|
|
|
- name: Build and upload
|
|
uses: tauri-apps/tauri-action@v0
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
|
|
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
|
|
with:
|
|
releaseId: ${{ needs.prepare.outputs.release_id }}
|
|
args: ${{ matrix.args }}
|
|
|
|
publish:
|
|
needs: [prepare, build]
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Verify manifest is complete, then publish
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
REPO: ${{ github.repository }}
|
|
TAG: ${{ needs.prepare.outputs.tag }}
|
|
run: |
|
|
gh release download "$TAG" --repo "$REPO" --pattern latest.json --output latest.json --clobber
|
|
echo "Platforms in latest.json:"
|
|
jq '.platforms | keys' latest.json
|
|
for key in darwin-aarch64 darwin-x86_64 linux-x86_64; do
|
|
if ! jq -e ".platforms[\"$key\"].url" latest.json > /dev/null; then
|
|
echo "::error::latest.json is missing platform '$key' — refusing to publish a partial update manifest. Re-run the release."
|
|
exit 1
|
|
fi
|
|
done
|
|
gh release edit "$TAG" --repo "$REPO" --draft=false --latest
|
|
|
|
# Arch gets its own package rather than the AppImage. The AppImage carries Ubuntu's GTK stack,
|
|
# which cannot talk to a modern Wayland compositor and silently falls back to Xwayland; a package
|
|
# linked against the system webkit2gtk runs as a native Wayland client. Runs after publish so it
|
|
# can only ever point at a release that survived the manifest check.
|
|
aur:
|
|
needs: [prepare, publish]
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
# The tag, not main, so the template and the licence are the ones this release shipped.
|
|
- uses: actions/checkout@v7
|
|
with:
|
|
ref: ${{ needs.prepare.outputs.tag }}
|
|
|
|
- name: Render the PKGBUILD for this release
|
|
env:
|
|
VERSION: ${{ needs.prepare.outputs.version }}
|
|
REPO: ${{ github.repository }}
|
|
run: |
|
|
URL="https://github.com/$REPO/releases/download/v$VERSION/Margin.Calendar_${VERSION}_amd64.deb"
|
|
# From the published asset, so the checksum is of the artifact users will actually fetch.
|
|
curl -fsSL --retry 3 -o package.deb "$URL"
|
|
SHA=$(sha256sum package.deb | cut -d' ' -f1)
|
|
# The PKGBUILD fetches the licence from the tag, so checksum the copy at that same tag.
|
|
LICENSE_SHA=$(sha256sum LICENSE | cut -d' ' -f1)
|
|
sed -e "s/@VERSION@/$VERSION/g" \
|
|
-e "s/@SHA256@/$SHA/g" \
|
|
-e "s/@LICENSE_SHA256@/$LICENSE_SHA/g" \
|
|
packaging/aur/PKGBUILD.in > PKGBUILD
|
|
echo "pkgver $VERSION, deb $SHA, licence $LICENSE_SHA"
|
|
|
|
- name: Generate .SRCINFO
|
|
# makepkg is Arch-only and refuses to run as root, hence the container and the throwaway
|
|
# user. --printsrcinfo parses the PKGBUILD, it does not build anything.
|
|
run: |
|
|
docker run --rm -v "$PWD:/w" -w /w archlinux:base-devel bash -c '
|
|
useradd -m builder && chown -R builder /w
|
|
su builder -c "makepkg --printsrcinfo" > .SRCINFO'
|
|
cat .SRCINFO
|
|
|
|
- name: Push to the AUR
|
|
env:
|
|
AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
|
|
VERSION: ${{ needs.prepare.outputs.version }}
|
|
run: |
|
|
if [ -z "$AUR_SSH_PRIVATE_KEY" ]; then
|
|
echo "::warning::AUR_SSH_PRIVATE_KEY is not set, so the AUR package was built but not published. The release itself is unaffected."
|
|
exit 0
|
|
fi
|
|
mkdir -p ~/.ssh && chmod 700 ~/.ssh
|
|
printf '%s\n' "$AUR_SSH_PRIVATE_KEY" > ~/.ssh/aur
|
|
chmod 600 ~/.ssh/aur
|
|
ssh-keyscan -t ed25519,rsa aur.archlinux.org >> ~/.ssh/known_hosts 2>/dev/null
|
|
export GIT_SSH_COMMAND="ssh -i ~/.ssh/aur -o IdentitiesOnly=yes"
|
|
git clone ssh://[email protected]/margin-calendar-bin.git aur
|
|
cp PKGBUILD .SRCINFO aur/
|
|
cd aur
|
|
# A package that does not exist yet clones as an empty repo, where the local branch name
|
|
# is whatever git defaults to. The AUR only accepts master.
|
|
git checkout -B master
|
|
git config user.name "github-actions[bot]"
|
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
git add PKGBUILD .SRCINFO
|
|
if git diff --cached --quiet; then
|
|
echo "AUR is already at this version, nothing to push."
|
|
exit 0
|
|
fi
|
|
git commit -m "margin-calendar-bin $VERSION"
|
|
git push origin master
|