Files
goodbuddy/.github/workflows/packages.yml
T
mesalogo 60119a4317
Deploy website to GitHub Pages / Deploy static website (push) Waiting to run
Cross-platform packages / Validate source (push) Waiting to run
Cross-platform packages / linux arm64 (push) Blocked by required conditions
Cross-platform packages / macos arm64 (push) Blocked by required conditions
Cross-platform packages / windows arm64 (push) Blocked by required conditions
Cross-platform packages / linux x64 (push) Blocked by required conditions
Cross-platform packages / macos x64 (push) Blocked by required conditions
Cross-platform packages / windows x64 (push) Blocked by required conditions
Cross-platform packages / Publish GitHub and OSS release (push) Blocked by required conditions
fix: align mirror publishing region
The v0.10.3 release index was generated, but the pinned upload client rejected object uploads because V4 signing did not receive a region. The application and website also addressed the Beijing bucket through the previous Hangzhou endpoint.

Derive and pass the endpoint region to every upload, pin workflow configuration to the trusted production bucket, and align application and website URL validation with its actual endpoint. Advance recovery metadata to 0.10.4 and remove the unpublished 0.10.3 note.

Release note: 0.10.4 carries forward the approved mirror-node and conversation timestamp improvements from the unpublished candidates.
2026-08-17 22:17:43 +08:00

325 lines
11 KiB
YAML

name: Cross-platform packages
on:
workflow_dispatch:
push:
branches:
- main
tags:
- 'v*'
permissions:
contents: read
concurrency:
group: packages-${{ github.ref }}
cancel-in-progress: ${{ github.ref_type != 'tag' }}
jobs:
validate:
name: Validate source
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: 24
cache: npm
- name: Verify release tag version
if: github.ref_type == 'tag'
run: node -e "const p=require('./package.json'); const expected='v'+p.version; if(process.env.GITHUB_REF_NAME!==expected){throw new Error('Expected tag '+expected+', received '+process.env.GITHUB_REF_NAME)}"
- name: Verify bilingual release notes
if: github.ref_type == 'tag'
run: npm run release:notes:verify
- name: Install dependencies
run: npm ci
- name: Run validators
run: |
npm test
npm run typecheck
npm run lint
- name: Build production bundle
run: npm run build:bundle
- name: Upload production bundle
if: github.event_name == 'workflow_dispatch' || github.ref_type == 'tag'
uses: actions/upload-artifact@v7
with:
name: goodbuddy-production-bundle
path: out
if-no-files-found: error
retention-days: 1
package:
name: ${{ matrix.platform }} ${{ matrix.arch }}
if: github.event_name == 'workflow_dispatch' || github.ref_type == 'tag'
needs: validate
strategy:
fail-fast: false
matrix:
include:
- platform: windows
arch: x64
runner: windows-2025
- platform: windows
arch: arm64
runner: windows-2025
- platform: macos
arch: x64
runner: macos-15-intel
- platform: macos
arch: arm64
runner: macos-15
- platform: linux
arch: x64
runner: ubuntu-24.04
- platform: linux
arch: arm64
runner: ubuntu-24.04-arm
runs-on: ${{ matrix.runner }}
timeout-minutes: 75
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: 24
cache: npm
- name: Cache packaging toolsets
uses: actions/cache@v6
with:
path: |
${{ runner.temp }}/electron
${{ runner.temp }}/electron-builder
key: packaging-${{ runner.os }}-${{ matrix.arch }}-${{ hashFiles('package-lock.json') }}
restore-keys: packaging-${{ runner.os }}-${{ matrix.arch }}-
- name: Install dependencies
run: npm ci
env:
ELECTRON_CACHE: ${{ runner.temp }}/electron
- name: Download production bundle
uses: actions/download-artifact@v8
with:
name: goodbuddy-production-bundle
path: out
- name: Build and verify release packages
run: npm run release:package -- --platform ${{ matrix.platform }} --arch ${{ matrix.arch }} --skip-build
env:
ELECTRON_CACHE: ${{ runner.temp }}/electron
ELECTRON_BUILDER_CACHE: ${{ runner.temp }}/electron-builder
- name: Upload release packages
uses: actions/upload-artifact@v7
with:
name: goodbuddy-${{ matrix.platform }}-${{ matrix.arch }}
path: dist/release/${{ matrix.platform }}-${{ matrix.arch }}
if-no-files-found: error
compression-level: 0
retention-days: 30
release:
name: Publish GitHub and OSS release
if: github.event_name == 'push' && github.ref_type == 'tag'
needs: package
runs-on: ubuntu-24.04
timeout-minutes: 35
environment:
name: aliyun-oss-release
permissions:
contents: write
actions: read
id-token: write
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- uses: actions/setup-node@v7
with:
node-version: 24
- name: Verify release tag
shell: bash
run: |
set -euo pipefail
expected="v$(node -p "require('./package.json').version")"
test "$GITHUB_REF_NAME" = "$expected"
test "$(git rev-parse "refs/tags/$GITHUB_REF_NAME^{commit}")" = "$GITHUB_SHA"
- name: Prepare bilingual release notes
run: node build/release-notes.cjs --output release-notes.md
- name: Download Windows packages
uses: actions/download-artifact@v8
with:
pattern: goodbuddy-windows-*
path: dist/release-downloads
- name: Download macOS packages
uses: actions/download-artifact@v8
with:
pattern: goodbuddy-macos-*
path: dist/release-downloads
- name: Download Linux packages
uses: actions/download-artifact@v8
with:
pattern: goodbuddy-linux-*
path: dist/release-downloads
- name: Verify and aggregate release assets
run: node build/aggregate-release.cjs --input dist/release-downloads --output dist/release-upload
- name: Verify OSS release configuration
shell: bash
env:
OSS_BUCKET: ${{ vars.ALIYUN_OSS_BUCKET }}
OSS_ENDPOINT: ${{ vars.ALIYUN_OSS_ENDPOINT }}
OIDC_PROVIDER_ARN: ${{ vars.ALIYUN_OIDC_PROVIDER_ARN }}
ROLE_ARN: ${{ vars.ALIYUN_ROLE_ARN }}
run: |
set -euo pipefail
test -n "$OSS_BUCKET"
test -n "$OSS_ENDPOINT"
test -n "$OIDC_PROVIDER_ARN"
test -n "$ROLE_ARN"
case "$OSS_BUCKET" in
goodbuddy) ;;
*) echo "OSS Bucket 必须与应用内置镜像地址一致" >&2; exit 1 ;;
esac
case "$OSS_ENDPOINT" in
https://oss-cn-beijing.aliyuncs.com) ;;
*) echo "OSS Endpoint 必须与应用内置镜像地址一致" >&2; exit 1 ;;
esac
case "$OIDC_PROVIDER_ARN" in
acs:ram::*:oidc-provider/*) ;;
*) echo "OIDC Provider ARN 无效" >&2; exit 1 ;;
esac
case "$ROLE_ARN" in
acs:ram::*:role/*) ;;
*) echo "RAM Role ARN 无效" >&2; exit 1 ;;
esac
- name: Authenticate to Alibaba Cloud
uses: aliyun/configure-aliyun-credentials-action@v1
with:
role-to-assume: ${{ vars.ALIYUN_ROLE_ARN }}
oidc-provider-arn: ${{ vars.ALIYUN_OIDC_PROVIDER_ARN }}
role-session-name: goodbuddy-release-${{ github.run_id }}
role-session-expiration: 3600
audience: sts.aliyuncs.com
- name: Install ossutil
shell: bash
run: |
set -euo pipefail
version="2.3.0"
archive="$RUNNER_TEMP/ossutil.zip"
directory="$RUNNER_TEMP/ossutil"
curl --fail --silent --show-error --location \
"https://gosspublic.alicdn.com/ossutil/v2/$version/ossutil-$version-linux-amd64.zip" \
--output "$archive"
mkdir "$directory"
unzip -q "$archive" -d "$directory"
binary="$(find "$directory" -type f -name ossutil -print -quit)"
test -n "$binary"
chmod +x "$binary"
echo "$(dirname "$binary")" >> "$GITHUB_PATH"
- name: Prepare OSS website release index
id: oss-release
shell: bash
env:
OSS_BUCKET: ${{ vars.ALIYUN_OSS_BUCKET }}
OSS_ENDPOINT: ${{ vars.ALIYUN_OSS_ENDPOINT }}
run: |
set -euo pipefail
endpoint_host="${OSS_ENDPOINT#https://}"
oss_region="${endpoint_host#oss-}"
oss_region="${oss_region%.aliyuncs.com}"
case "$oss_region" in
*[!a-z0-9-]*|'') echo "无法从 OSS Endpoint 推导 Region" >&2; exit 1 ;;
esac
base_url="https://${OSS_BUCKET}.${endpoint_host}/releases/${GITHUB_REF_NAME}/"
node build/create-site-release.cjs \
--manifest dist/release-upload/release-manifest.json \
--base-url "$base_url" \
--output dist/site-release.json
echo "base-url=$base_url" >> "$GITHUB_OUTPUT"
echo "region=$oss_region" >> "$GITHUB_OUTPUT"
- name: Upload immutable release assets to OSS
shell: bash
env:
OSS_BUCKET: ${{ vars.ALIYUN_OSS_BUCKET }}
OSS_ENDPOINT: ${{ vars.ALIYUN_OSS_ENDPOINT }}
OSS_REGION: ${{ steps.oss-release.outputs.region }}
run: |
set -euo pipefail
export OSS_ACCESS_KEY_ID="$ALIBABA_CLOUD_ACCESS_KEY_ID"
export OSS_ACCESS_KEY_SECRET="$ALIBABA_CLOUD_ACCESS_KEY_SECRET"
export OSS_SESSION_TOKEN="$ALIBABA_CLOUD_SECURITY_TOKEN"
test -n "$OSS_ACCESS_KEY_ID"
test -n "$OSS_ACCESS_KEY_SECRET"
test -n "$OSS_SESSION_TOKEN"
test -n "$OSS_REGION"
for file in dist/release-upload/* dist/site-release.json; do
name="$(basename "$file")"
ossutil cp "$file" \
"oss://${OSS_BUCKET}/releases/${GITHUB_REF_NAME}/${name}" \
--endpoint "$OSS_ENDPOINT" \
--region "$OSS_REGION" \
--update
done
- name: Verify public OSS release assets
run: node build/verify-site-release.cjs --manifest dist/site-release.json
- name: Create or update draft GitHub release
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
tag="$GITHUB_REF_NAME"
version="$(node -p "require('./package.json').version")"
if gh release view "$tag" >/dev/null 2>&1; then
gh release edit "$tag" --draft --title "GoodBuddy $version" --notes-file release-notes.md
else
gh release create "$tag" --draft --verify-tag --title "GoodBuddy $version" --notes-file release-notes.md
fi
gh release upload "$tag" dist/release-upload/* --clobber
gh release edit "$tag" --draft=false --latest
- name: Point website to verified OSS release
shell: bash
env:
OSS_BUCKET: ${{ vars.ALIYUN_OSS_BUCKET }}
OSS_ENDPOINT: ${{ vars.ALIYUN_OSS_ENDPOINT }}
OSS_REGION: ${{ steps.oss-release.outputs.region }}
run: |
set -euo pipefail
export OSS_ACCESS_KEY_ID="$ALIBABA_CLOUD_ACCESS_KEY_ID"
export OSS_ACCESS_KEY_SECRET="$ALIBABA_CLOUD_ACCESS_KEY_SECRET"
export OSS_SESSION_TOKEN="$ALIBABA_CLOUD_SECURITY_TOKEN"
test -n "$OSS_REGION"
ossutil cp dist/site-release.json \
"oss://${OSS_BUCKET}/releases/latest.json" \
--endpoint "$OSS_ENDPOINT" \
--region "$OSS_REGION" \
--force