mirror of
https://github.com/veeso/termscp.git
synced 2026-09-05 20:01:24 -07:00
afbc74113f
Deploy docs to GitHub Pages / deploy (push) Has been cancelled
Site / build-site (push) Has been cancelled
Install.sh / build (macos-latest) (push) Has been cancelled
Install.sh / build (ubuntu-latest) (push) Has been cancelled
CI / toolchain (push) Has been cancelled
CI / fmt (push) Has been cancelled
CI / install-scripts (push) Has been cancelled
CI / crates-ubuntu-latest (push) Has been cancelled
CI / crates-windows-latest (push) Has been cancelled
CI / doc (push) Has been cancelled
CI / deny (push) Has been cancelled
CI / crates-macos-latest (push) Has been cancelled
* ci: migrate project automation to Just Centralize build, test, release, dependency, hook, and website commands in Just recipes. Pin workflow tooling, use the repository toolchain, and run the complete validation set in CI. * ci: codex being codex * docs: update CLAUDE.md for just task runner migration Reflect the switch to just recipes for build/test/clippy/fmt, note dprint replacing raw rustfmt, and add a cross-platform code requirement. * fix: resolve clippy warnings breaking CI on ubuntu and windows Use clone() instead of implicit to_string() on already-owned String values, gate the windows-only unused make_file_at import behind cfg(posix), and fix unused mut / manual assign-op in the windows-only localhost test. * fix: fmt
467 lines
15 KiB
YAML
467 lines
15 KiB
YAML
name: Release
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
version:
|
|
description: "Version to release, e.g. 1.1.0 (no leading v)"
|
|
required: true
|
|
type: string
|
|
dry_run:
|
|
description: "Dry run: build & compute everything, push/publish nothing"
|
|
required: true
|
|
type: boolean
|
|
default: true
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
prepare:
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
version: ${{ inputs.version }}
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
token: ${{ secrets.RELEASE_PAT }}
|
|
persist-credentials: true
|
|
fetch-depth: 0
|
|
fetch-tags: true
|
|
|
|
- name: Validate version
|
|
env:
|
|
VERSION: ${{ inputs.version }}
|
|
run: |
|
|
if [[ ! "$VERSION" =~ ^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$ ]]; then
|
|
echo "invalid release version: $VERSION (expected MAJOR.MINOR.PATCH)" >&2
|
|
exit 2
|
|
fi
|
|
|
|
- name: Configure git identity
|
|
run: |
|
|
git config user.name "veeso"
|
|
git config user.email "christian.visintin@veeso.dev"
|
|
|
|
- name: Install git-cliff
|
|
uses: taiki-e/install-action@37f7c5781271959fb65b6b35224e28652ff2b63d # v2.87.0
|
|
with:
|
|
tool: git-cliff
|
|
|
|
- name: Install just
|
|
uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4
|
|
|
|
- name: Bump version
|
|
env:
|
|
VERSION: ${{ inputs.version }}
|
|
run: dist/release/bump_version.sh "$VERSION" "$(date +%F)"
|
|
|
|
- name: Generate CHANGELOG
|
|
env:
|
|
VERSION: ${{ inputs.version }}
|
|
run: just changelog "$VERSION"
|
|
|
|
- name: Generate release notes
|
|
env:
|
|
VERSION: ${{ inputs.version }}
|
|
run: git-cliff --unreleased --tag "v$VERSION" --strip header -o RELEASE_NOTES.md
|
|
|
|
- name: Upload release notes
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: release-notes
|
|
path: RELEASE_NOTES.md
|
|
retention-days: 1
|
|
if-no-files-found: error
|
|
|
|
- name: Show diff (dry run)
|
|
if: ${{ inputs.dry_run }}
|
|
run: git --no-pager diff
|
|
|
|
- name: Commit & push version bump
|
|
if: ${{ !inputs.dry_run }}
|
|
env:
|
|
VERSION: ${{ inputs.version }}
|
|
run: |
|
|
rm -f RELEASE_NOTES.md
|
|
git add -A
|
|
git commit -m "chore: release v$VERSION"
|
|
git push origin HEAD:main
|
|
|
|
build:
|
|
needs: prepare
|
|
name: build-${{ matrix.target }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- target: x86_64-unknown-linux-gnu
|
|
os: ubuntu-latest
|
|
kind: linux
|
|
deb_suffix: amd64
|
|
- target: aarch64-unknown-linux-gnu
|
|
os: ubuntu-24.04-arm
|
|
kind: linux
|
|
deb_suffix: arm64
|
|
- target: aarch64-apple-darwin
|
|
os: macos-latest
|
|
kind: macos
|
|
features: "--features smb-vendored"
|
|
- target: x86_64-apple-darwin
|
|
os: macos-latest
|
|
kind: macos
|
|
features: "--no-default-features --features keyring"
|
|
- target: x86_64-pc-windows-msvc
|
|
os: windows-latest
|
|
kind: windows
|
|
- target: aarch64-pc-windows-msvc
|
|
os: windows-11-arm
|
|
kind: windows
|
|
runs-on: ${{ matrix.os }}
|
|
env:
|
|
VERSION: ${{ needs.prepare.outputs.version }}
|
|
TARGET: ${{ matrix.target }}
|
|
FEATURES: ${{ matrix.features }}
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
ref: ${{ inputs.dry_run && github.sha || 'main' }}
|
|
persist-credentials: false
|
|
fetch-depth: 0
|
|
fetch-tags: true
|
|
- name: Install just
|
|
uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4
|
|
- name: Install Rust target
|
|
if: matrix.kind != 'windows'
|
|
run: rustup target add "$TARGET"
|
|
- name: Install Rust target
|
|
if: matrix.kind == 'windows'
|
|
run: rustup target add "$env:TARGET"
|
|
|
|
# ---- Linux: native per-arch build (x86_64 on ubuntu-latest, aarch64 on ubuntu-24.04-arm) ----
|
|
- name: Install dependencies (Linux)
|
|
if: matrix.kind == 'linux'
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y \
|
|
make \
|
|
libgit2-dev \
|
|
build-essential \
|
|
pkg-config \
|
|
libbsd-dev \
|
|
libcap-dev \
|
|
libcups2-dev \
|
|
libgnutls28-dev \
|
|
libicu-dev \
|
|
libjansson-dev \
|
|
libkeyutils-dev \
|
|
libldap2-dev \
|
|
zlib1g-dev \
|
|
libpam0g-dev \
|
|
libacl1-dev \
|
|
libarchive-dev \
|
|
flex \
|
|
bison \
|
|
libntirpc-dev \
|
|
libtracker-sparql-3.0-dev \
|
|
libglib2.0-dev \
|
|
libdbus-1-dev \
|
|
libsasl2-dev \
|
|
libunistring-dev \
|
|
cpanminus
|
|
sudo cpanm Parse::Yapp::Driver
|
|
cargo install cargo-deb
|
|
- name: Build (Linux)
|
|
if: matrix.kind == 'linux'
|
|
run: just build_release "$TARGET" "--features smb-vendored"
|
|
- name: Build deb (Linux)
|
|
if: matrix.kind == 'linux'
|
|
run: just package_deb "$TARGET"
|
|
|
|
# ---- macOS ----
|
|
- name: Install deps (macOS)
|
|
if: matrix.kind == 'macos'
|
|
run: |
|
|
brew update
|
|
brew install bison cpanminus cups flex gettext gmp gnutls icu4c jansson \
|
|
libarchive libbsd libunistring libgit2 libtirpc openldap pkg-config zlib
|
|
for p in bison cups flex gettext gmp gnutls icu4c jansson libarchive \
|
|
libbsd libgit2 libtirpc libunistring openldap zlib; do brew link --force "$p"; done
|
|
cpanm Parse::Yapp::Driver
|
|
- name: Build (macOS)
|
|
if: matrix.kind == 'macos'
|
|
run: just build_release "$TARGET" "$FEATURES"
|
|
|
|
# ---- Windows ----
|
|
- name: Build (Windows)
|
|
if: matrix.kind == 'windows'
|
|
run: just build_release "$env:TARGET" "--features smb-vendored"
|
|
|
|
# ---- Package posix (tar.gz) ----
|
|
- name: Package (posix)
|
|
if: matrix.kind != 'windows'
|
|
run: |
|
|
mkdir -p artifact
|
|
cp "target/$TARGET/release/termscp" artifact/termscp
|
|
tar -czf "artifact/termscp-v$VERSION-$TARGET.tar.gz" -C artifact termscp
|
|
shasum -a 256 "artifact/termscp-v$VERSION-$TARGET.tar.gz" | awk '{print $1}' > "artifact/$TARGET.sha256"
|
|
|
|
# ---- Package windows (zip) ----
|
|
- name: Package (windows)
|
|
if: matrix.kind == 'windows'
|
|
shell: pwsh
|
|
run: |
|
|
New-Item -ItemType Directory -Force artifact | Out-Null
|
|
Copy-Item "target/$env:TARGET/release/termscp.exe" artifact/termscp.exe
|
|
Compress-Archive -Path artifact/termscp.exe -DestinationPath "artifact/termscp-v$env:VERSION-$env:TARGET.zip"
|
|
(Get-FileHash "artifact/termscp-v$env:VERSION-$env:TARGET.zip" -Algorithm SHA256).Hash.ToLower() | Out-File -NoNewline "artifact/$env:TARGET.sha256"
|
|
|
|
- name: Move deb into artifact dir (Linux)
|
|
if: matrix.kind == 'linux'
|
|
run: cp target/"$TARGET"/debian/*.deb artifact/
|
|
|
|
- name: Upload build artifacts
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: build-${{ matrix.target }}
|
|
path: artifact/*
|
|
retention-days: 1
|
|
if-no-files-found: error
|
|
|
|
publish-homebrew:
|
|
needs: [prepare, build]
|
|
runs-on: ubuntu-latest
|
|
env:
|
|
VERSION: ${{ needs.prepare.outputs.version }}
|
|
steps:
|
|
- name: Download build artifacts
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
pattern: build-*
|
|
path: dl
|
|
merge-multiple: true
|
|
|
|
- name: Checkout homebrew tap
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
repository: veeso/homebrew-termscp
|
|
token: ${{ secrets.RELEASE_PAT }}
|
|
path: tap
|
|
persist-credentials: true
|
|
|
|
- name: Rewrite formula
|
|
run: |
|
|
set -euo pipefail
|
|
cd "$GITHUB_WORKSPACE"
|
|
SHA_MAC_ARM=$(cat dl/aarch64-apple-darwin.sha256)
|
|
SHA_MAC_X64=$(cat dl/x86_64-apple-darwin.sha256)
|
|
SHA_LIN_ARM=$(cat dl/aarch64-unknown-linux-gnu.sha256)
|
|
SHA_LIN_X64=$(cat dl/x86_64-unknown-linux-gnu.sha256)
|
|
BASE="https://github.com/veeso/termscp/releases/latest/download"
|
|
cat > tap/Formula/termscp.rb <<EOF
|
|
class Termscp < Formula
|
|
desc "A feature rich terminal file transfer and explorer with support for SCP/SFTP/FTP/S3/Kube/SMB/WebDAV"
|
|
homepage "https://termscp.rs/"
|
|
license "MIT"
|
|
version "$VERSION"
|
|
|
|
on_macos do
|
|
depends_on "bison"
|
|
depends_on "cups"
|
|
depends_on "flex"
|
|
depends_on "gettext"
|
|
depends_on "gmp"
|
|
depends_on "gnutls"
|
|
depends_on "icu4c"
|
|
depends_on "jansson"
|
|
depends_on "libarchive"
|
|
depends_on "libbsd"
|
|
depends_on "libgit2"
|
|
depends_on "libtirpc"
|
|
depends_on "libunistring"
|
|
depends_on "openldap"
|
|
depends_on "zlib"
|
|
|
|
on_arm do
|
|
url "$BASE/termscp-v$VERSION-aarch64-apple-darwin.tar.gz"
|
|
sha256 "$SHA_MAC_ARM"
|
|
end
|
|
on_intel do
|
|
url "$BASE/termscp-v$VERSION-x86_64-apple-darwin.tar.gz"
|
|
sha256 "$SHA_MAC_X64"
|
|
end
|
|
end
|
|
|
|
on_linux do
|
|
depends_on "dbus"
|
|
|
|
on_arm do
|
|
url "$BASE/termscp-v$VERSION-aarch64-unknown-linux-gnu.tar.gz"
|
|
sha256 "$SHA_LIN_ARM"
|
|
end
|
|
on_intel do
|
|
url "$BASE/termscp-v$VERSION-x86_64-unknown-linux-gnu.tar.gz"
|
|
sha256 "$SHA_LIN_X64"
|
|
end
|
|
end
|
|
|
|
def install
|
|
bin.install "termscp"
|
|
end
|
|
end
|
|
EOF
|
|
|
|
- name: Show formula (dry run)
|
|
if: ${{ inputs.dry_run }}
|
|
run: cat tap/Formula/termscp.rb
|
|
|
|
- name: Commit & push formula
|
|
if: ${{ !inputs.dry_run }}
|
|
run: |
|
|
cd tap
|
|
git config user.name "veeso"
|
|
git config user.email "christian.visintin@veeso.dev"
|
|
git add Formula/termscp.rb
|
|
git commit -m "termscp $VERSION"
|
|
git push
|
|
|
|
release:
|
|
needs: [prepare, build]
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: write
|
|
env:
|
|
VERSION: ${{ needs.prepare.outputs.version }}
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
token: ${{ secrets.RELEASE_PAT }}
|
|
ref: ${{ inputs.dry_run && github.sha || 'main' }}
|
|
persist-credentials: true
|
|
|
|
- name: Download build artifacts
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
pattern: build-*
|
|
path: dl
|
|
merge-multiple: true
|
|
|
|
- name: Download release notes
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: release-notes
|
|
path: notes
|
|
|
|
- name: Patch chocolatey checksums & pack
|
|
run: |
|
|
set -euo pipefail
|
|
SHA_WIN_X64=$(cat dl/x86_64-pc-windows-msvc.sha256)
|
|
SHA_WIN_ARM=$(cat dl/aarch64-pc-windows-msvc.sha256)
|
|
PS=dist/chocolatey/tools/chocolateyinstall.ps1
|
|
# arm checksum is the first $checksum line, x64 the second (matches file order)
|
|
SHA_WIN_ARM="$SHA_WIN_ARM" SHA_WIN_X64="$SHA_WIN_X64" \
|
|
perl -0pi -e 'BEGIN{our $n=0} s/(\$checksum\s*=\s*'"'"')[0-9a-f]*('"'"')/ $n++==0 ? "${1}$ENV{SHA_WIN_ARM}${2}" : "${1}$ENV{SHA_WIN_X64}${2}" /ge' "$PS"
|
|
docker run --rm -v "$PWD/dist/chocolatey:/work" -w /work \
|
|
chocolatey/choco:latest choco pack --output-directory /work
|
|
|
|
- name: Assemble release assets
|
|
run: |
|
|
mkdir -p out
|
|
cp dl/*.tar.gz dl/*.deb dl/*.zip out/ 2>/dev/null || true
|
|
cp dist/chocolatey/*.nupkg out/
|
|
|
|
- name: Upload assets artifact (dry run)
|
|
if: ${{ inputs.dry_run }}
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: release-assets-dryrun
|
|
path: out/*
|
|
retention-days: 3
|
|
|
|
- name: Create GitHub release
|
|
if: ${{ !inputs.dry_run }}
|
|
env:
|
|
GH_TOKEN: ${{ secrets.RELEASE_PAT }}
|
|
run: |
|
|
gh release create "v$VERSION" out/* \
|
|
--title "v$VERSION" \
|
|
--notes-file notes/RELEASE_NOTES.md
|
|
|
|
publish-crate:
|
|
needs: [prepare, release]
|
|
if: ${{ !inputs.dry_run }}
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
id-token: write
|
|
env:
|
|
VERSION: ${{ needs.prepare.outputs.version }}
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
ref: main
|
|
persist-credentials: false
|
|
fetch-depth: 0
|
|
fetch-tags: true
|
|
- name: Install just
|
|
uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4
|
|
|
|
- name: Install dependencies (Linux)
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y \
|
|
make \
|
|
libgit2-dev \
|
|
build-essential \
|
|
pkg-config \
|
|
libbsd-dev \
|
|
libcap-dev \
|
|
libcups2-dev \
|
|
libgnutls28-dev \
|
|
libicu-dev \
|
|
libjansson-dev \
|
|
libkeyutils-dev \
|
|
libldap2-dev \
|
|
zlib1g-dev \
|
|
libpam0g-dev \
|
|
libacl1-dev \
|
|
libarchive-dev \
|
|
flex \
|
|
bison \
|
|
libntirpc-dev \
|
|
libtracker-sparql-3.0-dev \
|
|
libglib2.0-dev \
|
|
libdbus-1-dev \
|
|
libsasl2-dev \
|
|
libunistring-dev \
|
|
cpanminus
|
|
sudo cpanm Parse::Yapp::Driver
|
|
|
|
- name: Authenticate to crates.io
|
|
id: auth
|
|
uses: rust-lang/crates-io-auth-action@c6f97d42243bad5fab37ca0427f495c86d5b1a18 # v1.0.5
|
|
|
|
- name: Publish to crates.io
|
|
env:
|
|
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
|
|
run: just publish_crate
|
|
|
|
publish-choco:
|
|
needs: [prepare, release]
|
|
if: ${{ !inputs.dry_run }}
|
|
runs-on: windows-latest
|
|
env:
|
|
VERSION: ${{ needs.prepare.outputs.version }}
|
|
steps:
|
|
- name: Download nupkg from release
|
|
env:
|
|
GH_TOKEN: ${{ secrets.RELEASE_PAT }}
|
|
run: gh release download "v$env:VERSION" --repo veeso/termscp --pattern "*.nupkg"
|
|
|
|
- name: Push to Chocolatey
|
|
env:
|
|
CHOCO_API_KEY: ${{ secrets.CHOCO_API_KEY }}
|
|
run: |
|
|
choco apikey --key $env:CHOCO_API_KEY --source https://push.chocolatey.org/
|
|
choco push (Get-ChildItem *.nupkg).Name --source https://push.chocolatey.org/
|