Skip to content

ci: assemble complete latest.json across all platforms #201

ci: assemble complete latest.json across all platforms

ci: assemble complete latest.json across all platforms #201

Workflow file for this run

name: Release Beta
on:
push:
branches:
- main
issue_comment:
types: [created]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
update_beta_ref:
runs-on: ubuntu-latest
if: ${{ github.event_name != 'issue_comment' || (github.event.issue.number == 69 && contains(github.event.comment.body, '/release-beta')) }}
steps:
- name: Create or update ref
id: create-or-update-ref
uses: ovsds/create-or-update-ref-action@v1
env:
GITHUB_TOKEN: ${{ secrets.MY_TOKEN }}
with:
ref: refs/tags/beta
sha: ${{ github.sha }}
release_beta:
needs: update_beta_ref
strategy:
fail-fast: false
matrix:
include:
- os: macos-latest
target: x86_64-apple-darwin
args:
- os: ubuntu-22.04
target: x86_64-unknown-linux-gnu
args:
- os: windows-latest
target: x86_64-pc-windows-msvc
args: --bundles nsis,updater
- os: macos-latest
target: aarch64-apple-darwin
args:
- os: windows-latest
target: aarch64-pc-windows-msvc
args: --bundles nsis,updater
- os: ubuntu-22.04-arm
target: aarch64-unknown-linux-gnu
args:
runs-on: ${{ matrix.os }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
repository: AlistGo/desktop
token: ${{ secrets.MY_TOKEN }}
- name: Install dependencies (ubuntu only)
if: ${{ contains(matrix.target, 'unknown-linux-gnu') }}
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libayatana-appindicator3-dev librsvg2-dev
- name: Rust setup
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Rust cache
uses: swatinem/rust-cache@v2
with:
workspaces: "./src-tauri -> target"
- uses: pnpm/action-setup@v2
with:
version: 9
run_install: false
- name: Sync node version and setup cache
uses: actions/setup-node@v4
with:
node-version: "lts/*"
cache: "pnpm"
- name: Install app dependencies and build web
run: pnpm i
- name: Replace version
run: |
npx tsx ./scripts/beta_version.ts
cat src-tauri/tauri.conf.json
env:
AD_VERSION: ${{ github.ref_name }}
TARGET_TRIPLE: ${{ matrix.target }}
- name: Get Rclone version
id: get-rclone-version
uses: fangqiuming/latest-release-version@v1.2.0-beta
with:
repository: rclone/rclone
token: ${{ secrets.GITHUB_TOKEN }}
- name: Download sidecar
run: npx tsx ./scripts/bin.ts
env:
TARGET_TRIPLE: ${{ matrix.target }}
ALIST_VERSION: beta
RCLONE_VERSION: ${{ steps.get-rclone-version.outputs.tag_name }}
- name: Clean conflicting macOS app tarballs
if: ${{ contains(matrix.target, 'apple-darwin') }}
uses: actions/github-script@v7
with:
github-token: ${{ secrets.MY_TOKEN }}
script: |
const [owner, repo] = process.env.GITHUB_REPOSITORY.split("/");
const tag = "beta";
const target = "${{ matrix.target }}";
const patterns =
target === "x86_64-apple-darwin"
? [/^alist-desktop_x64\.app\.tar\.gz$/, /^alist-desktop_x64\.app\.tar\.gz\.sig$/]
: target === "aarch64-apple-darwin"
? [/^alist-desktop_aarch64\.app\.tar\.gz$/, /^alist-desktop_aarch64\.app\.tar\.gz\.sig$/]
: [];
if (patterns.length === 0) return;
const rel = await github.rest.repos.getReleaseByTag({ owner, repo, tag });
const assets = await github.paginate(github.rest.repos.listReleaseAssets, { owner, repo, release_id: rel.data.id, per_page: 100 });
for (const a of assets) {
if (patterns.some(rx => rx.test(a.name))) {
await github.rest.repos.deleteReleaseAsset({ owner, repo, asset_id: a.id });
}
}
- name: Build & publish (coordinator uploads latest.json)
if: ${{ matrix.os == 'macos-latest' && matrix.target == 'x86_64-apple-darwin' }}
uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.MY_TOKEN }}
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
with:
releaseName: "AList Desktop v__VERSION__"
releaseBody: "See the assets to download and install this version."
args: "--target ${{ matrix.target }} ${{ matrix.args }}"
prerelease: true
tagName: beta
- name: Build & publish (no updater json)
if: ${{ !(matrix.os == 'macos-latest' && matrix.target == 'x86_64-apple-darwin') }}
uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.MY_TOKEN }}
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
with:
releaseName: "AList Desktop v__VERSION__"
releaseBody: "See the assets to download and install this version."
args: "--target ${{ matrix.target }} ${{ matrix.args }}"
prerelease: true
tagName: beta
includeUpdaterJson: false
build_updater:
name: "Build updater beta"
needs: release_beta
environment: ${{ github.event.inputs.environment || 'Beta' }}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: main
- uses: pnpm/action-setup@v2
with:
version: 9
run_install: false
- name: Sync node version and setup cache
uses: actions/setup-node@v4
with:
node-version: "lts/*"
- name: Generate proxy.json
run: |
npx tsx ./proxy.ts
- name: Upload proxy.json
uses: softprops/action-gh-release@v2
with:
token: ${{ secrets.MY_TOKEN }}
tag_name: beta
prerelease: true
make_latest: false
allow_updates: true
fail_on_unmatched_files: true
files: |
*.proxy.json
compose_latest_json:
name: "Compose complete latest.json beta"
needs: release_beta
runs-on: ubuntu-latest
steps:
- name: Assemble latest.json from every platform's updater assets
uses: actions/github-script@v7
with:
github-token: ${{ secrets.MY_TOKEN }}
script: |
const [owner, repo] = process.env.GITHUB_REPOSITORY.split("/");
const tag = "beta";
const rel = await github.rest.repos.getReleaseByTag({ owner, repo, tag });
const assets = await github.paginate(github.rest.repos.listReleaseAssets, {
owner, repo, release_id: rel.data.id, per_page: 100,
});
const byName = new Map(assets.map((a) => [a.name, a]));
const downloadUrl = (name) =>
`https://github.com/${owner}/${repo}/releases/download/${tag}/${encodeURIComponent(name)}`;
async function readSig(name) {
const a = byName.get(name + ".sig");
if (!a) return null;
const res = await github.request(
"GET /repos/{owner}/{repo}/releases/assets/{asset_id}",
{ owner, repo, asset_id: a.id, headers: { accept: "application/octet-stream" } }
);
return Buffer.from(res.data).toString("utf8").trim();
}
// First non-.sig asset whose name matches the regex.
const pick = (re) =>
(assets.find((a) => re.test(a.name) && !a.name.endsWith(".sig")) || {}).name;
const macX = pick(/^alist-desktop_x64\.app\.tar\.gz$/);
const macA = pick(/^alist-desktop_aarch64\.app\.tar\.gz$/);
const winXmsi = pick(/_x64_en-US\.msi\.zip$/);
const winXnsis = pick(/_x64-setup\.nsis\.zip$/);
const winA = pick(/_arm64-setup\.nsis\.zip$/);
const linX = pick(/_amd64\.AppImage\.tar\.gz$/);
const linA = pick(/_aarch64\.AppImage\.tar\.gz$/);
const platforms = {};
async function add(key, name) {
if (!name) return;
const signature = await readSig(name);
if (signature == null) {
core.warning(`no .sig for ${name}, skipping ${key}`);
return;
}
platforms[key] = { signature, url: downloadUrl(name) };
}
await add("darwin-x86_64", macX);
await add("darwin-x86_64-app", macX);
await add("darwin-aarch64", macA);
await add("darwin-aarch64-app", macA);
await add("windows-x86_64", winXmsi || winXnsis);
if (winXmsi) await add("windows-x86_64-msi", winXmsi);
if (winXnsis) await add("windows-x86_64-nsis", winXnsis);
await add("windows-aarch64", winA);
await add("windows-aarch64-nsis", winA);
await add("linux-x86_64", linX);
await add("linux-aarch64", linA);
if (Object.keys(platforms).length === 0) {
core.setFailed("No updater artifacts found; latest.json not composed");
return;
}
let version = tag.replace(/^v/, "");
const versioned = winXnsis || winXmsi || winA || linX || linA || "";
const vm = versioned.match(/alist-desktop_([0-9][^_]*)_/);
if (vm) version = vm[1];
const latest = {
version,
notes: "See the assets to download and install this version.",
pub_date: new Date().toISOString(),
platforms,
};
const body = JSON.stringify(latest, null, 2);
core.info("Composed latest.json:\n" + body);
const existing = byName.get("latest.json");
if (existing) {
await github.rest.repos.deleteReleaseAsset({ owner, repo, asset_id: existing.id });
}
await github.rest.repos.uploadReleaseAsset({
owner, repo, release_id: rel.data.id,
name: "latest.json",
data: body,
headers: {
"content-type": "application/json",
"content-length": Buffer.byteLength(body),
},
});
core.info(`Uploaded latest.json with platforms: ${Object.keys(platforms).join(", ")}`);