mirror of
https://github.com/narrrl/proton-drive-linux.git
synced 2026-11-03 16:41:26 +01:00
- scripts/publish-wiki.sh publishes every page listed in SECTIONS, copies images, writes a sectioned sidebar and footer, and removes stale pages. --check fails on links to missing files or headings and on docs pages that are neither published nor excluded. - New wiki.yml runs the check on pull requests and pushes to main, and publishes when release.yml calls it or when started by hand. - Split USER_GUIDE.md into topic pages (files, synced folders, photos, sharing, computers, launcher and tray); add Getting started and FAQ. - Make the COPR repository the main Fedora path, with update and uninstall steps for every package type. - Fix the stale CAPTCHA note in CLI.md, document pdfs unlock and lock, and drop the broken AGENTS.md link from CONTRIBUTING.md.
343 lines
11 KiB
YAML
343 lines
11 KiB
YAML
name: Release
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- 'v*'
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: write
|
|
|
|
jobs:
|
|
checks:
|
|
name: Release quality gates
|
|
runs-on: ubuntu-24.04
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v7
|
|
|
|
- name: Install system dependencies
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y \
|
|
pkg-config \
|
|
libfuse3-dev \
|
|
libgtk-4-dev \
|
|
libadwaita-1-dev \
|
|
libwebkitgtk-6.0-dev \
|
|
libsecret-1-dev \
|
|
libdbus-1-dev
|
|
|
|
- name: Set up Rust
|
|
uses: actions-rust-lang/setup-rust-toolchain@v1
|
|
with:
|
|
toolchain: '1.96'
|
|
components: rustfmt, clippy
|
|
cache: false
|
|
|
|
# A tag can read the caches of main but its own caches are useless to the next
|
|
# tag, so this only restores what CI saved on main.
|
|
- name: Cache Cargo target
|
|
uses: swatinem/rust-cache@v2
|
|
with:
|
|
shared-key: debug
|
|
save-if: false
|
|
|
|
- name: Verify tag and manifest versions
|
|
if: startsWith(github.ref, 'refs/tags/')
|
|
shell: bash
|
|
run: |
|
|
tag_version="${GITHUB_REF_NAME#v}"
|
|
manifest_version="$(sed -n 's/^version = "\([^"]*\)"/\1/p' Cargo.toml | head -n1)"
|
|
pkgbuild_version="$(sed -n 's/^pkgver=//p' packaging/PKGBUILD | head -n1)"
|
|
spec_version="$(sed -n 's/^%{!?version: %global version \([^}]*\)}/\1/p' packaging/proton-drive-linux.spec)"
|
|
test "$tag_version" = "$manifest_version"
|
|
test "$tag_version" = "$pkgbuild_version"
|
|
test "$tag_version" = "$spec_version"
|
|
|
|
- name: Release quality gates
|
|
run: |
|
|
cargo fmt --all -- --check
|
|
cargo clippy --workspace --all-targets -- -D warnings
|
|
cargo test --workspace --locked
|
|
scripts/fuse-acceptance.sh --offline-only
|
|
|
|
build-release:
|
|
name: Build packages
|
|
runs-on: ubuntu-24.04
|
|
environment: 'rpm signing'
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v7
|
|
|
|
- name: Install system dependencies
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y \
|
|
pkg-config \
|
|
libfuse3-dev \
|
|
libgtk-4-dev \
|
|
libadwaita-1-dev \
|
|
libwebkitgtk-6.0-dev \
|
|
libsecret-1-dev \
|
|
libdbus-1-dev \
|
|
desktop-file-utils \
|
|
gettext \
|
|
rpm
|
|
|
|
- name: Set up Rust
|
|
uses: actions-rust-lang/setup-rust-toolchain@v1
|
|
with:
|
|
toolchain: '1.96'
|
|
cache: false
|
|
|
|
# Restores the release-profile dependencies that CI builds on main.
|
|
- name: Cache Cargo target
|
|
uses: swatinem/rust-cache@v2
|
|
with:
|
|
shared-key: release
|
|
save-if: false
|
|
|
|
- name: Build release binaries
|
|
run: |
|
|
cargo build --release --locked
|
|
|
|
- name: Determine version
|
|
run: |
|
|
if [[ $GITHUB_REF == refs/tags/* ]]; then
|
|
# Extract version from tag (e.g. v0.1.0 -> 0.1.0)
|
|
VERSION=${GITHUB_REF#refs/tags/}
|
|
VERSION=${VERSION#v}
|
|
else
|
|
# Fallback for manual workflow runs: extract version from Cargo.toml
|
|
VERSION=$(grep -m1 '^version' Cargo.toml | cut -d'"' -f2)
|
|
VERSION="${VERSION}-dev-${GITHUB_SHA::7}"
|
|
fi
|
|
echo "VERSION=$VERSION" >> $GITHUB_ENV
|
|
echo "Building version: $VERSION"
|
|
|
|
- name: Package raw binaries (.tar.gz)
|
|
run: |
|
|
mkdir -p dist/binaries
|
|
cp target/release/pdfs dist/binaries/
|
|
cp target/release/pdfs-tray dist/binaries/
|
|
cp target/release/pdfs-app dist/binaries/
|
|
cp target/release/pdfs-prompt dist/binaries/
|
|
po/build.sh dist/binaries/locale
|
|
|
|
# Create tarball
|
|
tar -czf proton-drive-linux-${{ env.VERSION }}-x86_64.tar.gz -C dist/binaries .
|
|
|
|
# Every crate the build needs, so COPR can build the spec without network.
|
|
- name: Package vendored crates (.tar.xz)
|
|
run: |
|
|
cargo vendor --locked dist/vendor > /dev/null
|
|
tar -cJf proton-drive-linux-vendor-${{ env.VERSION }}.tar.xz -C dist vendor
|
|
|
|
- name: Package Debian package (.deb)
|
|
run: |
|
|
mkdir -p deb/DEBIAN
|
|
mkdir -p deb/usr/bin
|
|
mkdir -p deb/usr/share/applications
|
|
mkdir -p deb/usr/share/icons/hicolor/scalable/apps
|
|
mkdir -p deb/usr/share/licenses/proton-drive-linux
|
|
mkdir -p deb/usr/lib/systemd/user
|
|
mkdir -p deb/etc/xdg/autostart
|
|
|
|
# Copy binaries
|
|
cp target/release/pdfs deb/usr/bin/
|
|
cp target/release/pdfs-tray deb/usr/bin/
|
|
cp target/release/pdfs-app deb/usr/bin/
|
|
cp target/release/pdfs-prompt deb/usr/bin/
|
|
|
|
# Copy desktop integration files
|
|
cp packaging/io.narl.proton-drive-linux.desktop deb/usr/share/applications/
|
|
cp packaging/io.narl.proton-drive-linux-tray.desktop deb/etc/xdg/autostart/
|
|
cp packaging/io.narl.proton-drive-linux.svg deb/usr/share/icons/hicolor/scalable/apps/
|
|
cp packaging/proton-drive.service deb/usr/lib/systemd/user/
|
|
cp LICENSE deb/usr/share/licenses/proton-drive-linux/
|
|
po/build.sh deb/usr/share/locale
|
|
|
|
# Stops the running daemon before removal, so the mount stops mirroring deletes
|
|
install -m755 packaging/deb/prerm deb/DEBIAN/prerm
|
|
|
|
# Calculate Installed-Size in KB for the control file
|
|
INSTALLED_SIZE=$(du -sk deb | cut -f1)
|
|
|
|
# Write DEBIAN/control file
|
|
cat <<EOF > deb/DEBIAN/control
|
|
Package: proton-drive-linux
|
|
Version: ${{ env.VERSION }}
|
|
Section: utils
|
|
Priority: optional
|
|
Architecture: amd64
|
|
Maintainer: Nils Pukropp <contact@narl.io>
|
|
Depends: fuse3, libgtk-4-1 (>= 4.12.0), libadwaita-1-0 (>= 1.5.0), libsecret-1-0, libwebkitgtk-6.0-4, libimage-exiftool-perl
|
|
Installed-Size: ${INSTALLED_SIZE}
|
|
Homepage: https://proton-drive.narl.io
|
|
Description: Unofficial Proton Drive client for Linux
|
|
Files-on-demand Proton Drive for the Linux desktop, unaffiliated with Proton AG:
|
|
- FUSE virtual mount with block-level caching
|
|
- Scriptable command-line interface (pdfs)
|
|
- GTK4 desktop application, system tray, and search launcher
|
|
EOF
|
|
|
|
# Build Debian package
|
|
dpkg-deb --build deb proton-drive-linux_${{ env.VERSION }}_amd64.deb
|
|
|
|
- name: Package Fedora package (.rpm)
|
|
run: |
|
|
# Sanitize version (replace hyphens with dots for RPM compatibility)
|
|
RPM_VERSION=$(echo "${{ env.VERSION }}" | tr '-' '.')
|
|
|
|
# Create RPM build directories
|
|
mkdir -p rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS,BUILDROOT,db}
|
|
|
|
# Build RPM package
|
|
rpmbuild -bb \
|
|
--nodeps \
|
|
--define "_topdir $PWD/rpmbuild" \
|
|
--define "_sourcedir $PWD" \
|
|
--define "git_dir $PWD" \
|
|
--define "prebuilt 1" \
|
|
--define "version ${RPM_VERSION}" \
|
|
--define "_dbpath $PWD/rpmbuild/db" \
|
|
packaging/proton-drive-linux.spec
|
|
|
|
# Copy built RPM to root directory
|
|
cp rpmbuild/RPMS/x86_64/*.rpm .
|
|
|
|
- name: Sign Fedora package (.rpm)
|
|
env:
|
|
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
|
|
GPG_KEY_NAME: ${{ secrets.GPG_KEY_NAME }}
|
|
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
|
|
run: |
|
|
if [ -n "$GPG_PRIVATE_KEY" ] && [ -n "$GPG_KEY_NAME" ]; then
|
|
echo "$GPG_PRIVATE_KEY" | gpg --batch --pinentry-mode loopback --passphrase "$GPG_PASSPHRASE" --import
|
|
|
|
cat <<EOF > ~/.rpmmacros
|
|
%_signature gpg
|
|
%_gpg_name ${GPG_KEY_NAME}
|
|
%__gpg_sign_cmd %{__gpg} gpg --batch --verbose --no-armor --pinentry-mode loopback --passphrase %{_gpg_passphrase} --no-secmem-warning -u "%{_gpg_name}" -sbo %{__signature_filename} --digest-algo sha256 %{__plaintext_filename}
|
|
EOF
|
|
|
|
rpm --addsign --define "_gpg_passphrase $GPG_PASSPHRASE" *.rpm
|
|
else
|
|
echo "Skipping RPM signing: GPG_PRIVATE_KEY or GPG_KEY_NAME secret is not set."
|
|
fi
|
|
|
|
|
|
- name: Upload Workflow Artifacts
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: proton-drive-linux-builds
|
|
path: |
|
|
*.deb
|
|
*.tar.gz
|
|
*.tar.xz
|
|
*.rpm
|
|
if-no-files-found: error
|
|
|
|
# The flake is the Nix release: a tag is what `github:narrrl/proton-drive-linux/vX.Y.Z`
|
|
# pins, so it has to build before the release is announced.
|
|
nix:
|
|
name: Build the Nix package
|
|
runs-on: ubuntu-24.04
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
|
|
- uses: cachix/install-nix-action@v31
|
|
|
|
# Pulls from the project's binary cache, and pushes what this run built
|
|
# when the token is there; a fork's pull request has none and only pulls.
|
|
- uses: cachix/cachix-action@v17
|
|
with:
|
|
name: proton-drive-linux
|
|
authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
|
|
|
|
- name: Build the flake
|
|
run: nix build --print-build-logs .#proton-drive-linux
|
|
|
|
- name: Check the version
|
|
run: |
|
|
built="$(./result/bin/pdfs --version)"
|
|
echo "$built"
|
|
case "$GITHUB_REF" in
|
|
refs/tags/v*) grep -qF "${GITHUB_REF_NAME#v}" <<< "$built" ;;
|
|
esac
|
|
|
|
publish:
|
|
name: Create GitHub Release
|
|
needs: [checks, build-release, nix]
|
|
if: startsWith(github.ref, 'refs/tags/')
|
|
runs-on: ubuntu-24.04
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v7
|
|
|
|
- name: Download packages
|
|
uses: actions/download-artifact@v8
|
|
with:
|
|
name: proton-drive-linux-builds
|
|
|
|
# The release notes are this version's section of the changelog, from its
|
|
# heading up to the next one.
|
|
- name: Extract release notes
|
|
run: |
|
|
version="${GITHUB_REF_NAME#v}"
|
|
awk -v heading="## [$version]" \
|
|
'index($0, heading) == 1 { found = 1; print; next }
|
|
found && /^## \[/ { exit }
|
|
found' docs/CHANGELOG.md > release-notes.md
|
|
if [ ! -s release-notes.md ]; then
|
|
echo "::error::docs/CHANGELOG.md has no section for $version"
|
|
exit 1
|
|
fi
|
|
|
|
- name: Create GitHub Release
|
|
uses: softprops/action-gh-release@v3
|
|
with:
|
|
body_path: release-notes.md
|
|
files: |
|
|
*.deb
|
|
*.tar.gz
|
|
*.tar.xz
|
|
*.rpm
|
|
draft: false
|
|
prerelease: false
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
aur:
|
|
name: Publish AUR packages
|
|
needs: publish
|
|
if: startsWith(github.ref, 'refs/tags/')
|
|
uses: ./.github/workflows/aur.yml
|
|
with:
|
|
version: ${{ github.ref_name }}
|
|
secrets:
|
|
AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
|
|
|
|
copr:
|
|
name: Build COPR packages
|
|
needs: publish
|
|
if: startsWith(github.ref, 'refs/tags/')
|
|
uses: ./.github/workflows/copr.yml
|
|
with:
|
|
version: ${{ github.ref_name }}
|
|
secrets:
|
|
COPR_CONFIG: ${{ secrets.COPR_CONFIG }}
|
|
|
|
wiki:
|
|
name: Publish the wiki
|
|
needs: publish
|
|
if: startsWith(github.ref, 'refs/tags/')
|
|
uses: ./.github/workflows/wiki.yml
|
|
with:
|
|
ref: ${{ github.ref_name }}
|