mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-06 08:24:46 +00:00
Chromium checks its Linux sandbox before main.js, while package installation probes run as root and miss AppArmor restrictions on desktop users. Choose the launch flags before exec and always install the SUID alternative for native packages. Test published artifacts as an ordinary user with namespaces both denied and allowed; never repair permissions in the smoke harness.
599 lines
23 KiB
YAML
599 lines
23 KiB
YAML
name: Desktop Release
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- "v*"
|
|
- "desktop-v*"
|
|
- "desktop-macos-v*"
|
|
- "desktop-linux-v*"
|
|
- "desktop-windows-v*"
|
|
workflow_dispatch:
|
|
inputs:
|
|
tag:
|
|
description: "Existing tag to build (e.g. v0.1.0)"
|
|
required: true
|
|
type: string
|
|
platform:
|
|
description: "Optional desktop platform to build."
|
|
required: false
|
|
default: "all"
|
|
type: choice
|
|
options:
|
|
- all
|
|
- macos
|
|
- linux
|
|
- windows
|
|
checkout_ref:
|
|
description: "Optional branch/ref to checkout while using tag for release metadata."
|
|
required: false
|
|
default: ""
|
|
type: string
|
|
publish:
|
|
description: "Publish built artifacts to GitHub Releases."
|
|
required: false
|
|
default: "true"
|
|
type: choice
|
|
options:
|
|
- "true"
|
|
- "false"
|
|
rollout_hours:
|
|
description: "Linear rollout duration in hours. Use 0 for instant rollout."
|
|
required: false
|
|
default: "36"
|
|
type: string
|
|
|
|
concurrency:
|
|
group: desktop-release-${{ github.ref }}
|
|
cancel-in-progress: false
|
|
|
|
env:
|
|
SOURCE_TAG: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.tag || github.ref_name }}
|
|
CHECKOUT_REF: ${{ github.event_name == 'workflow_dispatch' && (github.event.inputs.checkout_ref || github.ref_name) || github.ref_name }}
|
|
SHOULD_PUBLISH: ${{ github.event_name != 'workflow_dispatch' || github.event.inputs.publish != 'false' }}
|
|
ROLLOUT_HOURS: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.rollout_hours || '36' }}
|
|
DESKTOP_PACKAGE_PATH: "packages/desktop"
|
|
|
|
jobs:
|
|
create-release:
|
|
if: ${{ (github.event_name == 'push' && !startsWith(github.ref_name, 'desktop-macos-v') && !startsWith(github.ref_name, 'desktop-linux-v') && !startsWith(github.ref_name, 'desktop-windows-v')) || (github.event_name == 'workflow_dispatch' && github.event.inputs.platform == 'all' && github.event.inputs.publish != 'false') }}
|
|
permissions:
|
|
contents: write
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
sparse-checkout: scripts
|
|
ref: ${{ env.CHECKOUT_REF }}
|
|
|
|
- name: Resolve release metadata
|
|
shell: bash
|
|
run: node scripts/emit-release-env.mjs --source-tag "$SOURCE_TAG" >> "$GITHUB_ENV"
|
|
|
|
- name: Create GitHub release
|
|
if: env.IS_SMOKE_TAG != 'true'
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
if node scripts/github-release.mjs --repo "${{ github.repository }}" --tag "$RELEASE_TAG" > /dev/null 2>&1; then
|
|
echo "Release $RELEASE_TAG already exists, skipping creation"
|
|
else
|
|
prerelease_flag=""
|
|
if [[ "$IS_PRERELEASE" == "true" ]]; then
|
|
prerelease_flag="--prerelease"
|
|
fi
|
|
gh release create "$RELEASE_TAG" \
|
|
--repo "${{ github.repository }}" \
|
|
--title "Paseo $RELEASE_TAG" \
|
|
--notes "" \
|
|
--draft \
|
|
$prerelease_flag || {
|
|
echo "Release creation raced with another workflow; continuing."
|
|
node scripts/github-release.mjs --repo "${{ github.repository }}" --tag "$RELEASE_TAG" > /dev/null
|
|
}
|
|
fi
|
|
|
|
publish-macos:
|
|
needs: [create-release]
|
|
if: ${{ always() && (needs.create-release.result == 'success' || needs.create-release.result == 'skipped') && ((github.event_name == 'workflow_dispatch' && (github.event.inputs.platform == 'all' || github.event.inputs.platform == 'macos')) || (github.event_name == 'push' && (startsWith(github.ref_name, 'v') || startsWith(github.ref_name, 'desktop-v') || startsWith(github.ref_name, 'desktop-macos-v')))) }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- runner: macos-14
|
|
electron_arch: arm64
|
|
- runner: macos-15-intel
|
|
electron_arch: x64
|
|
permissions:
|
|
contents: write
|
|
packages: read
|
|
runs-on: ${{ matrix.runner }}
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
ref: ${{ env.CHECKOUT_REF }}
|
|
|
|
- name: Resolve release metadata
|
|
shell: bash
|
|
run: node scripts/emit-release-env.mjs --source-tag "$SOURCE_TAG" >> "$GITHUB_ENV"
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "22"
|
|
cache: "npm"
|
|
cache-dependency-path: package-lock.json
|
|
registry-url: "https://npm.pkg.github.com"
|
|
scope: "@boudra"
|
|
|
|
- name: Install JS dependencies
|
|
run: node scripts/npm-retry.mjs ci
|
|
env:
|
|
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Set desktop package version from tag
|
|
shell: bash
|
|
run: |
|
|
node <<'NODE'
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
|
|
const version = process.env.DESKTOP_VERSION;
|
|
if (!version) throw new Error('DESKTOP_VERSION env var is missing');
|
|
|
|
const packageJsonPath = path.join(process.env.DESKTOP_PACKAGE_PATH, 'package.json');
|
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
packageJson.version = version;
|
|
fs.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`);
|
|
NODE
|
|
|
|
- name: Build desktop release
|
|
shell: bash
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
EP_GH_IGNORE_TIME: true
|
|
CSC_LINK: ${{ secrets.APPLE_CERTIFICATE }}
|
|
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
|
APPLE_ID: ${{ secrets.APPLE_ID }}
|
|
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
|
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
|
PASEO_DESKTOP_SMOKE: "1"
|
|
PASEO_DESKTOP_SMOKE_ARTIFACT_DIR: ${{ runner.temp }}/desktop-smoke
|
|
run: |
|
|
set -euo pipefail
|
|
build_args=(-- --publish never --mac --${{ matrix.electron_arch }})
|
|
build_args+=("-c.publish.releaseType=$RELEASE_TYPE")
|
|
build_args+=("-c.publish.channel=$RELEASE_CHANNEL")
|
|
npm run build:desktop "${build_args[@]}"
|
|
|
|
- name: Upload packaged smoke diagnostics
|
|
if: failure()
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: desktop-smoke-macos-${{ matrix.electron_arch }}
|
|
path: ${{ runner.temp }}/desktop-smoke
|
|
if-no-files-found: ignore
|
|
retention-days: 7
|
|
|
|
- name: Upload desktop artifacts to release
|
|
if: env.SHOULD_PUBLISH == 'true' && env.IS_SMOKE_TAG != 'true'
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
release_dir="${DESKTOP_PACKAGE_PATH}/release"
|
|
files=()
|
|
while IFS= read -r -d '' f; do
|
|
files+=("$f")
|
|
done < <(find "$release_dir" -maxdepth 1 -type f ! -name '*.yml' -print0 | sort -z)
|
|
if (( ${#files[@]} == 0 )); then
|
|
echo "::error::No release artifacts found in $release_dir"
|
|
exit 1
|
|
fi
|
|
release_lookup="$(node scripts/github-release.mjs --repo "${{ github.repository }}" --tag "$RELEASE_TAG")"
|
|
gh release upload "$release_lookup" "${files[@]}" --clobber --repo "${{ github.repository }}"
|
|
|
|
- name: Upload desktop artifacts to workflow
|
|
if: env.SHOULD_PUBLISH != 'true'
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: desktop-macos-${{ matrix.electron_arch }}
|
|
path: ${{ env.DESKTOP_PACKAGE_PATH }}/release/*.dmg
|
|
retention-days: 7
|
|
|
|
- name: Upload manifest artifact
|
|
if: env.SHOULD_PUBLISH == 'true' && env.IS_SMOKE_TAG != 'true'
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: mac-manifest-${{ matrix.electron_arch }}
|
|
path: ${{ env.DESKTOP_PACKAGE_PATH }}/release/${{ env.RELEASE_CHANNEL }}-mac.yml
|
|
retention-days: 1
|
|
|
|
publish-linux:
|
|
needs: [create-release]
|
|
if: ${{ always() && (needs.create-release.result == 'success' || needs.create-release.result == 'skipped') && ((github.event_name == 'workflow_dispatch' && (github.event.inputs.platform == 'all' || github.event.inputs.platform == 'linux')) || (github.event_name == 'push' && (startsWith(github.ref_name, 'v') || startsWith(github.ref_name, 'desktop-v') || startsWith(github.ref_name, 'desktop-linux-v')))) }}
|
|
permissions:
|
|
contents: write
|
|
packages: read
|
|
runs-on: ubuntu-24.04
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
ref: ${{ env.CHECKOUT_REF }}
|
|
|
|
- name: Resolve release metadata
|
|
shell: bash
|
|
run: node scripts/emit-release-env.mjs --source-tag "$SOURCE_TAG" >> "$GITHUB_ENV"
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "22"
|
|
cache: "npm"
|
|
cache-dependency-path: package-lock.json
|
|
registry-url: "https://npm.pkg.github.com"
|
|
scope: "@boudra"
|
|
|
|
- name: Install JS dependencies
|
|
run: node scripts/npm-retry.mjs ci
|
|
env:
|
|
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Set desktop package version from tag
|
|
shell: bash
|
|
run: |
|
|
node <<'NODE'
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
|
|
const version = process.env.DESKTOP_VERSION;
|
|
if (!version) throw new Error('DESKTOP_VERSION env var is missing');
|
|
|
|
const packageJsonPath = path.join(process.env.DESKTOP_PACKAGE_PATH, 'package.json');
|
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
packageJson.version = version;
|
|
fs.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`);
|
|
NODE
|
|
|
|
- name: Install Linux smoke display
|
|
run: sudo apt-get update && sudo apt-get install -y xvfb xauth rpm
|
|
|
|
- name: Build desktop release
|
|
shell: bash
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
EP_GH_IGNORE_TIME: true
|
|
PASEO_DESKTOP_SMOKE: "1"
|
|
PASEO_DESKTOP_SMOKE_ARTIFACT_DIR: ${{ runner.temp }}/desktop-smoke
|
|
run: |
|
|
set -euo pipefail
|
|
build_args=(-- --publish never --linux --x64)
|
|
build_args+=("-c.publish.releaseType=$RELEASE_TYPE")
|
|
build_args+=("-c.publish.channel=$RELEASE_CHANNEL")
|
|
npm run build:desktop "${build_args[@]}"
|
|
|
|
- name: Smoke installed artifacts with restricted user namespaces
|
|
run: |
|
|
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=1
|
|
if unshare --user --map-root-user --net true; then
|
|
echo "Expected the launching user's namespace probe to be denied"
|
|
exit 1
|
|
fi
|
|
sudo dpkg -i packages/desktop/release/*.deb
|
|
node packages/desktop/e2e/linux-artifact-smoke.js packages/desktop/release disabled
|
|
env:
|
|
PASEO_DESKTOP_SMOKE_ARTIFACT_DIR: ${{ runner.temp }}/desktop-smoke/restricted
|
|
|
|
- name: Smoke sandbox-preserving portable launches
|
|
run: |
|
|
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
|
|
unshare --user --map-root-user --net true
|
|
node packages/desktop/e2e/linux-artifact-smoke.js packages/desktop/release enabled
|
|
env:
|
|
PASEO_DESKTOP_SMOKE_ARTIFACT_DIR: ${{ runner.temp }}/desktop-smoke/userns
|
|
|
|
- name: Upload packaged smoke diagnostics
|
|
if: always()
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: desktop-smoke-linux-x64
|
|
path: ${{ runner.temp }}/desktop-smoke
|
|
if-no-files-found: ignore
|
|
retention-days: 7
|
|
|
|
- name: Upload desktop artifacts to release
|
|
if: env.SHOULD_PUBLISH == 'true' && env.IS_SMOKE_TAG != 'true'
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
release_dir="${DESKTOP_PACKAGE_PATH}/release"
|
|
files=()
|
|
while IFS= read -r -d '' f; do
|
|
files+=("$f")
|
|
done < <(find "$release_dir" -maxdepth 1 -type f ! -name '*.yml' -print0 | sort -z)
|
|
if (( ${#files[@]} == 0 )); then
|
|
echo "::error::No release artifacts found in $release_dir"
|
|
exit 1
|
|
fi
|
|
release_lookup="$(node scripts/github-release.mjs --repo "${{ github.repository }}" --tag "$RELEASE_TAG")"
|
|
gh release upload "$release_lookup" "${files[@]}" --clobber --repo "${{ github.repository }}"
|
|
|
|
- name: Upload desktop artifacts to workflow
|
|
if: env.SHOULD_PUBLISH != 'true'
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: desktop-linux
|
|
path: ${{ env.DESKTOP_PACKAGE_PATH }}/release/*
|
|
retention-days: 7
|
|
|
|
- name: Upload manifest artifact
|
|
if: env.SHOULD_PUBLISH == 'true' && env.IS_SMOKE_TAG != 'true'
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: linux-manifest
|
|
path: ${{ env.DESKTOP_PACKAGE_PATH }}/release/${{ env.RELEASE_CHANNEL }}-linux.yml
|
|
retention-days: 1
|
|
|
|
publish-windows:
|
|
needs: [create-release]
|
|
if: ${{ always() && (needs.create-release.result == 'success' || needs.create-release.result == 'skipped') && ((github.event_name == 'workflow_dispatch' && (github.event.inputs.platform == 'all' || github.event.inputs.platform == 'windows')) || (github.event_name == 'push' && (startsWith(github.ref_name, 'v') || startsWith(github.ref_name, 'desktop-v') || startsWith(github.ref_name, 'desktop-windows-v')))) }}
|
|
permissions:
|
|
contents: write
|
|
packages: read
|
|
runs-on: windows-latest
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
ref: ${{ env.CHECKOUT_REF }}
|
|
|
|
- name: Resolve release metadata
|
|
shell: bash
|
|
run: node scripts/emit-release-env.mjs --source-tag "$SOURCE_TAG" >> "$GITHUB_ENV"
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "22"
|
|
cache: "npm"
|
|
cache-dependency-path: package-lock.json
|
|
registry-url: "https://npm.pkg.github.com"
|
|
scope: "@boudra"
|
|
|
|
- name: Install JS dependencies
|
|
run: node scripts/npm-retry.mjs ci
|
|
env:
|
|
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Set desktop package version from tag
|
|
shell: bash
|
|
run: |
|
|
node <<'NODE'
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
|
|
const version = process.env.DESKTOP_VERSION;
|
|
if (!version) throw new Error('DESKTOP_VERSION env var is missing');
|
|
|
|
const packageJsonPath = path.join(process.env.DESKTOP_PACKAGE_PATH, 'package.json');
|
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
packageJson.version = version;
|
|
fs.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`);
|
|
NODE
|
|
|
|
- name: Build desktop release
|
|
shell: bash
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
EP_GH_IGNORE_TIME: true
|
|
PASEO_DESKTOP_SMOKE: "1"
|
|
PASEO_DESKTOP_SMOKE_ARTIFACT_DIR: ${{ runner.temp }}/desktop-smoke
|
|
run: |
|
|
set -euo pipefail
|
|
build_args=(-- --publish never --win --x64 --arm64)
|
|
build_args+=("-c.publish.releaseType=$RELEASE_TYPE")
|
|
build_args+=("-c.publish.channel=$RELEASE_CHANNEL")
|
|
npm run build:desktop "${build_args[@]}"
|
|
|
|
- name: Upload packaged smoke diagnostics
|
|
if: failure()
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: desktop-smoke-windows-x64
|
|
path: ${{ runner.temp }}/desktop-smoke
|
|
if-no-files-found: ignore
|
|
retention-days: 7
|
|
|
|
- name: Upload desktop artifacts to release
|
|
if: env.SHOULD_PUBLISH == 'true' && env.IS_SMOKE_TAG != 'true'
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
release_dir="${DESKTOP_PACKAGE_PATH}/release"
|
|
files=()
|
|
while IFS= read -r -d '' f; do
|
|
files+=("$f")
|
|
done < <(find "$release_dir" -maxdepth 1 -type f ! -name '*.yml' -print0 | sort -z)
|
|
if (( ${#files[@]} == 0 )); then
|
|
echo "::error::No release artifacts found in $release_dir"
|
|
exit 1
|
|
fi
|
|
release_lookup="$(node scripts/github-release.mjs --repo "${{ github.repository }}" --tag "$RELEASE_TAG")"
|
|
gh release upload "$release_lookup" "${files[@]}" --clobber --repo "${{ github.repository }}"
|
|
|
|
- name: Upload desktop artifacts to workflow
|
|
if: env.SHOULD_PUBLISH != 'true'
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: desktop-windows
|
|
path: ${{ env.DESKTOP_PACKAGE_PATH }}/release/*
|
|
retention-days: 7
|
|
|
|
- name: Upload manifest artifact
|
|
if: env.SHOULD_PUBLISH == 'true' && env.IS_SMOKE_TAG != 'true'
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: windows-manifest
|
|
path: ${{ env.DESKTOP_PACKAGE_PATH }}/release/${{ env.RELEASE_CHANNEL }}.yml
|
|
retention-days: 1
|
|
|
|
finalize-rollout:
|
|
needs: [publish-macos, publish-linux, publish-windows]
|
|
if: ${{ always() && (github.event_name != 'workflow_dispatch' || github.event.inputs.publish != 'false') }}
|
|
permissions:
|
|
contents: write
|
|
runs-on: ubuntu-latest
|
|
concurrency:
|
|
group: desktop-rollout-${{ github.event.inputs.tag || github.ref_name }}
|
|
cancel-in-progress: false
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
sparse-checkout: |
|
|
package.json
|
|
package-lock.json
|
|
scripts
|
|
ref: ${{ env.CHECKOUT_REF }}
|
|
|
|
- name: Resolve release tag
|
|
shell: bash
|
|
run: node scripts/emit-release-env.mjs --source-tag "$SOURCE_TAG" >> "$GITHUB_ENV"
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "22"
|
|
cache: "npm"
|
|
cache-dependency-path: package-lock.json
|
|
registry-url: "https://npm.pkg.github.com"
|
|
scope: "@boudra"
|
|
|
|
- name: Install JS dependencies
|
|
run: node scripts/npm-retry.mjs ci
|
|
env:
|
|
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Download mac manifest artifacts
|
|
if: env.IS_SMOKE_TAG != 'true' && needs.publish-macos.result == 'success'
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
pattern: mac-manifest-*
|
|
path: release-manifests
|
|
|
|
- name: Download Linux manifest artifact
|
|
if: env.IS_SMOKE_TAG != 'true' && needs.publish-linux.result == 'success'
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: linux-manifest
|
|
path: release-manifests/linux-manifest
|
|
|
|
- name: Download Windows manifest artifact
|
|
if: env.IS_SMOKE_TAG != 'true' && needs.publish-windows.result == 'success'
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: windows-manifest
|
|
path: release-manifests/windows-manifest
|
|
|
|
- name: Assemble manifests and publish release
|
|
if: env.IS_SMOKE_TAG != 'true'
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
cd release-manifests
|
|
manifests_dir="$PWD/final"
|
|
mkdir -p "$manifests_dir"
|
|
|
|
expected_manifests=(
|
|
"${RELEASE_CHANNEL}-mac.yml"
|
|
"${RELEASE_CHANNEL}-linux.yml"
|
|
"${RELEASE_CHANNEL}.yml"
|
|
)
|
|
release_lookup="$(node ../scripts/github-release.mjs --repo "${{ github.repository }}" --tag "$RELEASE_TAG" --cleanup-duplicates)"
|
|
existing_assets="$(gh release view "$release_lookup" --repo "${{ github.repository }}" --json assets --jq '.assets[].name')"
|
|
for manifest_name in "${expected_manifests[@]}"; do
|
|
if grep -Fxq "$manifest_name" <<< "$existing_assets"; then
|
|
case "$manifest_name" in
|
|
"${RELEASE_CHANNEL}-mac.yml") platform_result="${{ needs.publish-macos.result }}" ;;
|
|
"${RELEASE_CHANNEL}-linux.yml") platform_result="${{ needs.publish-linux.result }}" ;;
|
|
"${RELEASE_CHANNEL}.yml") platform_result="${{ needs.publish-windows.result }}" ;;
|
|
esac
|
|
if [[ "$platform_result" =~ ^(success|skipped)$ ]]; then
|
|
gh release download "$release_lookup" \
|
|
--repo "${{ github.repository }}" \
|
|
--pattern "$manifest_name" \
|
|
--dir "$manifests_dir"
|
|
else
|
|
gh release delete-asset "$release_lookup" "$manifest_name" \
|
|
--repo "${{ github.repository }}" \
|
|
--yes
|
|
fi
|
|
fi
|
|
done
|
|
|
|
if [[ "${{ needs.publish-macos.result }}" == "success" ]]; then
|
|
manifest_name="${RELEASE_CHANNEL}-mac.yml"
|
|
node ../scripts/merge-mac-manifest.mjs \
|
|
"mac-manifest-arm64/${manifest_name}" \
|
|
"mac-manifest-x64/${manifest_name}" \
|
|
"$manifests_dir/${manifest_name}"
|
|
fi
|
|
|
|
if [[ "${{ needs.publish-linux.result }}" == "success" ]]; then
|
|
cp "linux-manifest/${RELEASE_CHANNEL}-linux.yml" "$manifests_dir/"
|
|
fi
|
|
|
|
if [[ "${{ needs.publish-windows.result }}" == "success" ]]; then
|
|
cp "windows-manifest/${RELEASE_CHANNEL}.yml" "$manifests_dir/"
|
|
fi
|
|
|
|
shopt -s nullglob
|
|
files=( "$manifests_dir"/*.yml )
|
|
if (( ${#files[@]} == 0 )); then
|
|
echo "::error::No manifest artifacts were available to publish"
|
|
exit 1
|
|
fi
|
|
timestamp="$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")"
|
|
node ../scripts/stamp-rollout.mjs --release-date "$timestamp" --rollout-hours "$ROLLOUT_HOURS" "${files[@]}"
|
|
node ../scripts/validate-desktop-manifests.mjs \
|
|
--release-date "$timestamp" \
|
|
--rollout-hours "$ROLLOUT_HOURS" \
|
|
"${files[@]}"
|
|
gh release upload "$release_lookup" "${files[@]}" --clobber --repo "${{ github.repository }}"
|
|
|
|
failed_builds=()
|
|
[[ "${{ needs.publish-macos.result }}" =~ ^(success|skipped)$ ]] || failed_builds+=(macOS)
|
|
[[ "${{ needs.publish-linux.result }}" =~ ^(success|skipped)$ ]] || failed_builds+=(Linux)
|
|
[[ "${{ needs.publish-windows.result }}" =~ ^(success|skipped)$ ]] || failed_builds+=(Windows)
|
|
if (( ${#failed_builds[@]} > 0 )); then
|
|
echo "::error::Desktop builds did not complete for ${failed_builds[*]}; the release remains a draft"
|
|
exit 1
|
|
fi
|
|
|
|
missing_manifests=()
|
|
for manifest_name in "${expected_manifests[@]}"; do
|
|
[[ -f "$manifests_dir/$manifest_name" ]] || missing_manifests+=("$manifest_name")
|
|
done
|
|
if (( ${#missing_manifests[@]} > 0 )); then
|
|
echo "::error::Missing updater manifests: ${missing_manifests[*]}; the release remains a draft"
|
|
exit 1
|
|
fi
|
|
|
|
publish_args=(release edit "$release_lookup" --tag "$RELEASE_TAG" --draft=false --repo "${{ github.repository }}")
|
|
if [[ "$IS_PRERELEASE" == "true" ]]; then
|
|
publish_args+=(--prerelease)
|
|
fi
|
|
gh "${publish_args[@]}"
|