mirror of
https://github.com/nexu-io/open-design.git
synced 2026-06-01 03:14:35 +07:00
* i18n: add translations for media provider coming soon section (#2415) * i18n: add translations for media provider coming soon section - Add 'settings.mediaProviderComingSoonHint' key to all 19 locales - Replace hardcoded English strings in SettingsDialog.tsx with i18n keys - Reuse existing 'tasks.comingSoon' and 'settings.agentInstall.docs' keys - Resolves TODO(i18n) comment at line 5091 * fix: escape single quotes in translation strings * fix: escape all single quotes in English translation string * feat(release): upload browser sourcemaps to PostHog for packaged builds Next.js was emitting minified JS with no browser sourcemaps, so PostHog Error Tracking surfaces frames like fO / fz / s4 / tD instead of real file:line locations. This wires up the full pipeline: - apps/web/next.config.ts: enable productionBrowserSourceMaps so next build emits .js.map alongside each chunk. - tools/pack/src/web-sourcemaps.ts: new helper that runs after next build and before any packaging step copies the web output into the Electron resources. Uses @posthog/cli to inject chunk IDs and upload sourcemaps to PostHog, then ALWAYS strips every .map under .next/static so source never ships inside an installer (saves ~14 MB per packaged image too). - tools/pack/src/{mac/workspace,win/app,linux}.ts: call processWebSourcemaps immediately after the @open-design/web build step. - tools/pack/src/config.ts: read POSTHOG_CLI_API_KEY + POSTHOG_CLI_PROJECT_ID (with POSTHOG_PERSONAL_API_KEY / POSTHOG_PROJECT_ID aliases) and expose them on ToolPackConfig with the same shape as the existing posthogKey / posthogHost fields. - .github/workflows/release-{beta,preview,stable}.yml: pass the new secrets through so all three release channels symbolicate stacks. When the API key is missing (PR builds, forks, local contributor builds), the helper logs and skips the upload — but still strips .map files. The strip step is unconditional because shipping a sourcemap is equivalent to shipping the source. Adds tools/pack/tests/web-sourcemaps.test.ts covering: missing chunks dir silently noop, no-map noop, strip-only path when credentials are absent, recursive walker for nested subdirectories. CLI happy path is left to the release workflow itself. Required follow-up (cannot push from code): add a repo secret named POSTHOG_CLI_API_KEY (the phx_ personal API key) and a repo var named POSTHOG_CLI_PROJECT_ID (the numeric project id, 420348 for our project) in nexu-io/open-design settings before merging. * fix(web-sourcemaps): use management host for CLI, not ingest host POSTHOG_HOST is the ingest URL (us.i.posthog.com) used by the runtime SDK to POST events to /capture/. The @posthog/cli sourcemap upload talks to the **management** API (us.posthog.com) and gets a 404 on the ingest host. The two are not interchangeable. Adds a separate `posthogCliHost` field on ToolPackConfig sourced from POSTHOG_CLI_HOST (with no fallback to POSTHOG_HOST). When the env is unset the @posthog/cli defaults to the US Cloud app host on its own, which is correct for our project — so this PR doesn't need a new repo variable for it. --------- Co-authored-by: Nicholas-Xiong <2482929840@qq.com>
920 lines
38 KiB
YAML
920 lines
38 KiB
YAML
name: release-stable
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
channel:
|
|
description: "Release channel. nightly publishes to R2 only; stable also creates a GitHub Release and tag."
|
|
required: true
|
|
type: choice
|
|
options:
|
|
- stable
|
|
- nightly
|
|
default: stable
|
|
nightly_version:
|
|
description: "Required when channel=stable: exact validated nightly version to promote, for example 0.5.1.nightly.3."
|
|
required: false
|
|
type: string
|
|
|
|
permissions:
|
|
actions: write
|
|
contents: write
|
|
|
|
concurrency:
|
|
group: open-design-release-stable-${{ inputs.channel }}
|
|
cancel-in-progress: false
|
|
|
|
env:
|
|
OPEN_DESIGN_TELEMETRY_RELAY_URL: ${{ vars.OPEN_DESIGN_TELEMETRY_RELAY_URL }}
|
|
# PostHog product-analytics ingest. Defined as repository secret + var
|
|
# so official builds ship with analytics enabled; PR builds and forks
|
|
# without these run the daemon in no-op analytics mode (events never
|
|
# leave the user's machine, /api/analytics/config returns enabled=false).
|
|
POSTHOG_KEY: ${{ secrets.POSTHOG_KEY }}
|
|
POSTHOG_HOST: ${{ vars.POSTHOG_HOST }}
|
|
# PostHog Error tracking sourcemap upload. Personal API key (phx_...) and
|
|
# project ID let tools-pack's web-sourcemaps step ship browser sourcemaps
|
|
# to PostHog after `next build` and before the .map files are stripped
|
|
# from the packaged bundle. Missing in PR/fork builds → upload is skipped
|
|
# and the helper still strips .map to keep source out of the installer.
|
|
POSTHOG_CLI_API_KEY: ${{ secrets.POSTHOG_CLI_API_KEY }}
|
|
POSTHOG_CLI_PROJECT_ID: ${{ vars.POSTHOG_CLI_PROJECT_ID }}
|
|
|
|
jobs:
|
|
metadata:
|
|
name: Prepare release metadata
|
|
if: github.repository == 'nexu-io/open-design'
|
|
runs-on: ubuntu-latest
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
GITHUB_REPOSITORY: ${{ github.repository }}
|
|
OPEN_DESIGN_NIGHTLY_METADATA_URL: ${{ vars.CLOUDFLARE_R2_RELEASES_PUBLIC_ORIGIN }}/nightly/latest/metadata.json
|
|
OPEN_DESIGN_RELEASE_CHANNEL: ${{ inputs.channel }}
|
|
OPEN_DESIGN_RELEASES_PUBLIC_ORIGIN: ${{ vars.CLOUDFLARE_R2_RELEASES_PUBLIC_ORIGIN }}
|
|
OPEN_DESIGN_STABLE_NIGHTLY_VERSION: ${{ inputs.nightly_version }}
|
|
outputs:
|
|
base_version: ${{ steps.stable.outputs.base_version }}
|
|
branch: ${{ steps.stable.outputs.branch }}
|
|
channel: ${{ steps.stable.outputs.channel }}
|
|
commit: ${{ steps.stable.outputs.commit }}
|
|
github_release_enabled: ${{ steps.stable.outputs.github_release_enabled }}
|
|
nightly_number: ${{ steps.stable.outputs.nightly_number }}
|
|
previous_stable: ${{ steps.stable.outputs.previous_stable }}
|
|
release_name: ${{ steps.stable.outputs.release_name }}
|
|
release_version: ${{ steps.stable.outputs.release_version }}
|
|
stable_version: ${{ steps.stable.outputs.stable_version }}
|
|
state_source: ${{ steps.stable.outputs.state_source }}
|
|
version_tag: ${{ steps.stable.outputs.version_tag }}
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v6.0.2
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v6
|
|
with:
|
|
node-version: 24
|
|
|
|
- name: Prepare release metadata
|
|
id: stable
|
|
run: node --experimental-strip-types ./scripts/release-stable.ts
|
|
|
|
- name: Validate R2 release access
|
|
env:
|
|
AWS_ACCESS_KEY_ID: ${{ secrets.CLOUDFLARE_R2_RELEASES_AK }}
|
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.CLOUDFLARE_R2_RELEASES_SK }}
|
|
AWS_DEFAULT_REGION: auto
|
|
AWS_EC2_METADATA_DISABLED: "true"
|
|
CLOUDFLARE_R2_RELEASES_BUCKET: ${{ secrets.CLOUDFLARE_R2_RELEASES_BUCKET }}
|
|
CLOUDFLARE_R2_RELEASES_PUBLIC_ORIGIN: ${{ vars.CLOUDFLARE_R2_RELEASES_PUBLIC_ORIGIN }}
|
|
CLOUDFLARE_R2_RELEASES_URL: ${{ secrets.CLOUDFLARE_R2_RELEASES_URL }}
|
|
R2_ACCESS_PROBE_NAME: release-stable
|
|
RELEASE_CHANNEL: ${{ inputs.channel }}
|
|
run: bash .github/scripts/release/r2/check.sh
|
|
|
|
verify:
|
|
name: Verify build (typecheck + tests)
|
|
needs: metadata
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v6.0.2
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Setup pnpm
|
|
uses: pnpm/action-setup@v5
|
|
with:
|
|
version: 10.33.2
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v6
|
|
with:
|
|
node-version: 24
|
|
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
# `scripts/postinstall.mjs` auto-builds `packages/*` and `tools/*`, but
|
|
# `apps/daemon` and `apps/desktop` are not in that list. On a fresh clone
|
|
# (every CI run), workspace typecheck fails because:
|
|
# - packaged/runtime consumers resolve the daemon package export through
|
|
# generated `apps/daemon/dist/*.d.ts`
|
|
# - `apps/packaged/src/index.ts` dynamic-imports `@open-design/desktop/main`
|
|
# which resolves to `apps/desktop/dist/main/index.d.ts`
|
|
# Build them explicitly here. Keeps the root `typecheck` script untouched.
|
|
- name: Build daemon and desktop (typecheck dependencies)
|
|
run: |
|
|
pnpm --filter @open-design/daemon build
|
|
pnpm --filter @open-design/desktop build
|
|
|
|
- name: Typecheck workspaces
|
|
run: pnpm -r --workspace-concurrency=4 --if-present run typecheck
|
|
|
|
- name: Check repository layout policies
|
|
run: pnpm guard
|
|
|
|
# Workspace tests are intentionally not gated here. apps/web's
|
|
# i18n content-coverage tests assert that every locale carries
|
|
# display metadata for every prompt template / skill / design
|
|
# system. Those tests fail on `main` as of this writing because
|
|
# PR #187 added two new prompt templates without translating
|
|
# their metadata into the 9 ship-ready locales — an i18n drift
|
|
# that's out of scope for the release infrastructure. Tracked as
|
|
# a follow-up; revisit once locale metadata is back in sync.
|
|
|
|
build_mac:
|
|
name: Build release mac arm64
|
|
needs: [metadata, verify]
|
|
runs-on: macos-14
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v6.0.2
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Setup pnpm
|
|
uses: pnpm/action-setup@v5
|
|
with:
|
|
version: 10.33.2
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v6
|
|
with:
|
|
node-version: 24
|
|
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
- name: Verify mac Electron framework symlinks
|
|
run: |
|
|
set -euo pipefail
|
|
electron_dist="$(node -e 'const path = require("node:path"); const { createRequire } = require("node:module"); const requireFromDesktop = createRequire(path.join(process.cwd(), "apps/desktop/package.json")); const electron = requireFromDesktop.resolve("electron"); process.stdout.write(path.join(path.dirname(electron), "dist"));')"
|
|
framework="$electron_dist/Electron.app/Contents/Frameworks/Electron Framework.framework"
|
|
for link in \
|
|
"$framework/Electron Framework" \
|
|
"$framework/Helpers" \
|
|
"$framework/Libraries" \
|
|
"$framework/Resources" \
|
|
"$framework/Versions/Current"; do
|
|
if [ ! -L "$link" ]; then
|
|
echo "Expected Electron framework symlink, got non-symlink: $link" >&2
|
|
ls -la "$framework" >&2 || true
|
|
ls -la "$framework/Versions" >&2 || true
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
- name: Prepare Apple signing certificate
|
|
env:
|
|
APPLE_SIGNING_CERTIFICATE_BASE64: ${{ secrets.APPLE_SIGNING_CERTIFICATE_BASE64 }}
|
|
APPLE_SIGNING_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_SIGNING_CERTIFICATE_PASSWORD }}
|
|
run: |
|
|
set -euo pipefail
|
|
cert_path="$RUNNER_TEMP/open-design-signing.p12"
|
|
if ! printf '%s' "$APPLE_SIGNING_CERTIFICATE_BASE64" | base64 --decode > "$cert_path" 2>/dev/null; then
|
|
printf '%s' "$APPLE_SIGNING_CERTIFICATE_BASE64" | base64 -D > "$cert_path"
|
|
fi
|
|
{
|
|
echo "CSC_LINK=$cert_path"
|
|
echo "CSC_KEY_PASSWORD=$APPLE_SIGNING_CERTIFICATE_PASSWORD"
|
|
} >> "$GITHUB_ENV"
|
|
|
|
- name: Build release mac artifacts
|
|
env:
|
|
APPLE_ID: ${{ secrets.APPLE_ID }}
|
|
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
|
|
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
|
run: |
|
|
set -euo pipefail
|
|
tools_pack_dir="$RUNNER_TEMP/tools-pack"
|
|
build_json_path="$RUNNER_TEMP/mac-tools-pack-build.json"
|
|
build_log_path="$RUNNER_TEMP/mac-tools-pack-build.log"
|
|
rm -rf "$tools_pack_dir"
|
|
: > "$build_log_path"
|
|
build_args=(
|
|
exec tools-pack mac build
|
|
--dir "$tools_pack_dir"
|
|
--namespace release-stable
|
|
--portable
|
|
--app-version "${{ needs.metadata.outputs.release_version }}"
|
|
--mac-compression normal
|
|
--to all
|
|
--json
|
|
--signed
|
|
)
|
|
if build_output="$(pnpm "${build_args[@]}" 2> >(tee -a "$build_log_path" >&2))"; then
|
|
printf '%s\n' "$build_output" | tee "$build_json_path"
|
|
else
|
|
build_status=$?
|
|
printf '%s\n' "$build_output"
|
|
exit "$build_status"
|
|
fi
|
|
|
|
- name: Capture mac framework diagnostics
|
|
if: ${{ failure() }}
|
|
continue-on-error: true
|
|
run: |
|
|
set -euo pipefail
|
|
output="$RUNNER_TEMP/mac-framework-diagnostics.txt"
|
|
source_resolve_log="$RUNNER_TEMP/mac-framework-source-resolve.err"
|
|
source_framework="$(node -e 'const path = require("node:path"); const { createRequire } = require("node:module"); const requireFromDesktop = createRequire(path.join(process.cwd(), "apps/desktop/package.json")); const electron = requireFromDesktop.resolve("electron"); process.stdout.write(path.join(path.dirname(electron), "dist", "Electron.app", "Contents", "Frameworks", "Electron Framework.framework"));' 2>"$source_resolve_log" || true)"
|
|
app_name="Open Design.app"
|
|
if [ "${{ needs.metadata.outputs.channel }}" = "nightly" ]; then
|
|
app_name="Open Design Nightly.app"
|
|
fi
|
|
built_framework="$RUNNER_TEMP/tools-pack/out/mac/namespaces/release-stable/builder/mac-arm64/$app_name/Contents/Frameworks/Electron Framework.framework"
|
|
|
|
dump_framework() {
|
|
local label="$1"
|
|
local framework="$2"
|
|
echo "## $label"
|
|
echo "path=$framework"
|
|
if [ ! -e "$framework" ] && [ ! -L "$framework" ]; then
|
|
echo "missing"
|
|
return 0
|
|
fi
|
|
echo "### top-level"
|
|
ls -la "$framework" || true
|
|
echo "### symlinks"
|
|
find "$framework" -maxdepth 4 -type l -print0 | while IFS= read -r -d '' link; do
|
|
printf '%s -> %s\n' "$link" "$(readlink "$link")"
|
|
done || true
|
|
echo "### selected stat"
|
|
for path in \
|
|
"$framework" \
|
|
"$framework/Electron Framework" \
|
|
"$framework/Versions" \
|
|
"$framework/Versions/Current" \
|
|
"$framework/Versions/Current/Electron Framework" \
|
|
"$framework/Versions/A" \
|
|
"$framework/Versions/A/Electron Framework" \
|
|
"$framework/Resources" \
|
|
"$framework/Versions/A/Resources/Info.plist"; do
|
|
if [ -e "$path" ] || [ -L "$path" ]; then
|
|
stat -f '%Sp %HT %N' "$path" || true
|
|
else
|
|
echo "missing: $path"
|
|
fi
|
|
done
|
|
echo "### plist"
|
|
plutil -p "$framework/Versions/A/Resources/Info.plist" 2>&1 || true
|
|
echo "### codesign display"
|
|
codesign --display --verbose=4 "$framework/Electron Framework" 2>&1 || true
|
|
codesign --display --verbose=4 "$framework/Versions/Current/Electron Framework" 2>&1 || true
|
|
codesign --display --verbose=4 "$framework/Versions/A/Electron Framework" 2>&1 || true
|
|
codesign --display --verbose=4 "$framework" 2>&1 || true
|
|
}
|
|
|
|
{
|
|
date -u
|
|
if [ -n "$source_framework" ]; then
|
|
dump_framework "source Electron Framework" "$source_framework"
|
|
else
|
|
echo "## source Electron Framework"
|
|
echo "resolve failed"
|
|
cat "$source_resolve_log" || true
|
|
fi
|
|
dump_framework "built Electron Framework" "$built_framework"
|
|
} > "$output"
|
|
cat "$output"
|
|
|
|
- name: Upload mac build diagnostics
|
|
if: ${{ always() }}
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: open-design-stable-mac-build-diagnostics
|
|
path: |
|
|
${{ runner.temp }}/mac-tools-pack-build.log
|
|
${{ runner.temp }}/mac-tools-pack-build.json
|
|
${{ runner.temp }}/mac-framework-diagnostics.txt
|
|
if-no-files-found: warn
|
|
|
|
- name: Smoke release mac packaged runtime
|
|
working-directory: e2e
|
|
env:
|
|
OD_PACKAGED_E2E_BUILD_JSON_PATH: ${{ runner.temp }}/mac-tools-pack-build.json
|
|
OD_PACKAGED_E2E_BUILD_LOG_PATH: ${{ runner.temp }}/mac-tools-pack-build.log
|
|
OD_PACKAGED_E2E_MAC: "1"
|
|
OD_PACKAGED_E2E_NAMESPACE: release-stable
|
|
OD_PACKAGED_E2E_RELEASE_CHANNEL: ${{ needs.metadata.outputs.channel }}
|
|
OD_PACKAGED_E2E_RELEASE_VERSION: ${{ needs.metadata.outputs.release_version }}
|
|
OD_PACKAGED_E2E_REPORT_DIR: ${{ runner.temp }}/release-report/mac
|
|
OD_PACKAGED_E2E_TOOLS_PACK_DIR: ${{ runner.temp }}/tools-pack
|
|
run: |
|
|
set -euo pipefail
|
|
pnpm exec tsx scripts/release-smoke.ts mac specs/mac.spec.ts
|
|
|
|
- name: Upload mac e2e spec report
|
|
if: ${{ always() }}
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: open-design-release-mac-e2e-report
|
|
path: ${{ runner.temp }}/release-report/mac
|
|
if-no-files-found: warn
|
|
|
|
- name: Prepare mac release assets
|
|
id: assets
|
|
env:
|
|
CLOUDFLARE_R2_RELEASES_PUBLIC_ORIGIN: ${{ vars.CLOUDFLARE_R2_RELEASES_PUBLIC_ORIGIN }}
|
|
RELEASE_CHANNEL: ${{ needs.metadata.outputs.channel }}
|
|
RELEASE_NOTES: Open Design ${{ needs.metadata.outputs.release_version }}
|
|
RELEASE_VERSION: ${{ needs.metadata.outputs.release_version }}
|
|
TOOLS_PACK_NAMESPACE: release-stable
|
|
run: bash .github/scripts/release/assets/mac.sh
|
|
|
|
- name: Upload mac release bundle
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: open-design-release-mac-release-assets
|
|
path: ${{ runner.temp }}/release-assets
|
|
|
|
build_mac_intel:
|
|
name: Build release mac intel x64
|
|
needs: [metadata, verify]
|
|
runs-on: macos-15-intel
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v6.0.2
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Setup pnpm
|
|
uses: pnpm/action-setup@v5
|
|
with:
|
|
version: 10.33.2
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v6
|
|
with:
|
|
node-version: 24
|
|
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
- name: Prepare Apple signing certificate
|
|
env:
|
|
APPLE_SIGNING_CERTIFICATE_BASE64: ${{ secrets.APPLE_SIGNING_CERTIFICATE_BASE64 }}
|
|
APPLE_SIGNING_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_SIGNING_CERTIFICATE_PASSWORD }}
|
|
run: |
|
|
set -euo pipefail
|
|
cert_path="$RUNNER_TEMP/open-design-signing.p12"
|
|
if ! printf '%s' "$APPLE_SIGNING_CERTIFICATE_BASE64" | base64 --decode > "$cert_path" 2>/dev/null; then
|
|
printf '%s' "$APPLE_SIGNING_CERTIFICATE_BASE64" | base64 -D > "$cert_path"
|
|
fi
|
|
{
|
|
echo "CSC_LINK=$cert_path"
|
|
echo "CSC_KEY_PASSWORD=$APPLE_SIGNING_CERTIFICATE_PASSWORD"
|
|
} >> "$GITHUB_ENV"
|
|
|
|
- name: Build release mac intel artifacts
|
|
env:
|
|
APPLE_ID: ${{ secrets.APPLE_ID }}
|
|
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
|
|
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
|
run: |
|
|
set -euo pipefail
|
|
pnpm exec tools-pack mac build \
|
|
--dir "$RUNNER_TEMP/tools-pack" \
|
|
--namespace release-stable-intel \
|
|
--portable \
|
|
--app-version "${{ needs.metadata.outputs.release_version }}" \
|
|
--mac-compression normal \
|
|
--to all \
|
|
--json \
|
|
--signed
|
|
|
|
- name: Prepare mac intel release assets
|
|
id: assets
|
|
env:
|
|
RELEASE_CHANNEL: ${{ needs.metadata.outputs.channel }}
|
|
RELEASE_VERSION: ${{ needs.metadata.outputs.release_version }}
|
|
TOOLS_PACK_NAMESPACE: release-stable-intel
|
|
run: bash .github/scripts/release/assets/mac-intel.sh
|
|
|
|
- name: Upload mac intel release bundle
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: open-design-release-mac-intel-release-assets
|
|
path: ${{ runner.temp }}/release-assets
|
|
|
|
build_win:
|
|
name: Build release win x64
|
|
needs: [metadata, verify]
|
|
runs-on: windows-latest
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v6.0.2
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Setup pnpm
|
|
uses: pnpm/action-setup@v5
|
|
with:
|
|
version: 10.33.2
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v6
|
|
with:
|
|
node-version: 24
|
|
cache: pnpm
|
|
cache-dependency-path: pnpm-lock.yaml
|
|
|
|
- name: Compute Windows tools-pack cache key
|
|
id: win_tools_pack_cache_key
|
|
shell: pwsh
|
|
env:
|
|
WIN_TOOLS_PACK_ORIGIN_KEY: ${{ hashFiles('package.json', 'pnpm-lock.yaml', 'pnpm-workspace.yaml', 'apps/daemon/**', 'apps/web/**', 'apps/desktop/**', 'apps/packaged/**', 'packages/agui-adapter/**', 'packages/contracts/**', 'packages/plugin-runtime/**', 'packages/sidecar-proto/**', 'packages/sidecar/**', 'packages/platform/**', 'tools/pack/bin/**', 'tools/pack/package.json', 'tools/pack/resources/**', 'tools/pack/src/**', 'tools/pack/tsconfig.json', 'assets/community-pets/**', 'assets/frames/**', 'craft/**', 'design-systems/**', 'design-templates/**', 'plugins/_official/**', 'plugins/registry/**', 'prompt-templates/**', 'skills/**', '.github/workflows/release-stable.yml', '.github/scripts/release/cache/win.ps1') }}
|
|
run: |
|
|
if ([string]::IsNullOrWhiteSpace($env:WIN_TOOLS_PACK_ORIGIN_KEY)) {
|
|
throw "Windows tools-pack cache origin key is empty"
|
|
}
|
|
$prefix = "tools-pack-win-v7-stable-$env:RUNNER_OS-"
|
|
"origin=$env:WIN_TOOLS_PACK_ORIGIN_KEY" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
|
|
"prefix=$prefix" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
|
|
"key=$prefix$env:WIN_TOOLS_PACK_ORIGIN_KEY" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
|
|
|
|
- name: Restore Windows tools-pack cache
|
|
id: win_tools_pack_cache_restore
|
|
uses: actions/cache/restore@v5
|
|
continue-on-error: true
|
|
with:
|
|
path: ${{ runner.temp }}/tools-pack-cache
|
|
key: ${{ steps.win_tools_pack_cache_key.outputs.key }}
|
|
restore-keys: |
|
|
${{ steps.win_tools_pack_cache_key.outputs.prefix }}
|
|
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
- name: Setup NSIS
|
|
shell: pwsh
|
|
run: |
|
|
if ((Get-Command makensis.exe -ErrorAction SilentlyContinue) -or (Test-Path "C:\Program Files (x86)\NSIS\makensis.exe")) {
|
|
exit 0
|
|
}
|
|
choco install nsis -y --no-progress
|
|
|
|
- name: Build release windows artifacts
|
|
id: win_tools_pack_build
|
|
shell: pwsh
|
|
run: |
|
|
$ErrorActionPreference = "Stop"
|
|
$toolsPackDir = "${{ runner.temp }}/tools-pack"
|
|
$cacheDir = "${{ runner.temp }}/tools-pack-cache"
|
|
$buildJsonPath = Join-Path $env:RUNNER_TEMP "windows-tools-pack-build.json"
|
|
$buildArgs = @(
|
|
"exec", "tools-pack", "win", "build",
|
|
"--dir", $toolsPackDir,
|
|
"--cache-dir", $cacheDir,
|
|
"--namespace", "release-stable-win",
|
|
"--portable",
|
|
"--app-version", "${{ needs.metadata.outputs.release_version }}",
|
|
"--to", "nsis",
|
|
"--json"
|
|
)
|
|
"cache_failed=false" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
|
|
try {
|
|
$buildOutput = pnpm @buildArgs
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "Windows tools-pack cached build exited with code $LASTEXITCODE"
|
|
}
|
|
} catch {
|
|
Write-Warning "Windows tools-pack cached build failed; removing restored cache and retrying without cache."
|
|
"cache_failed=true" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
|
|
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue $cacheDir
|
|
$buildOutput = pnpm exec tools-pack win build `
|
|
--dir $toolsPackDir `
|
|
--namespace release-stable-win `
|
|
--portable `
|
|
--app-version "${{ needs.metadata.outputs.release_version }}" `
|
|
--to nsis `
|
|
--json
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "Windows tools-pack uncached fallback build exited with code $LASTEXITCODE"
|
|
}
|
|
}
|
|
$buildOutput | Set-Content -Path $buildJsonPath
|
|
$buildOutput
|
|
|
|
- name: Delete failed Windows tools-pack cache
|
|
if: ${{ steps.win_tools_pack_build.outputs.cache_failed == 'true' && steps.win_tools_pack_cache_restore.outputs.cache-matched-key != '' }}
|
|
shell: pwsh
|
|
continue-on-error: true
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
run: |
|
|
$matchedKey = "${{ steps.win_tools_pack_cache_restore.outputs.cache-matched-key }}"
|
|
$caches = @(gh cache list --key $matchedKey --limit 100 --json id,key,ref | ConvertFrom-Json | Where-Object { $_.key -eq $matchedKey })
|
|
foreach ($cache in $caches) {
|
|
gh cache delete $cache.id
|
|
}
|
|
"deletedFailedCacheKey=$matchedKey count=$($caches.Count)"
|
|
|
|
- name: Smoke release windows packaged runtime
|
|
working-directory: e2e
|
|
env:
|
|
OD_PACKAGED_E2E_BUILD_JSON_PATH: ${{ runner.temp }}/windows-tools-pack-build.json
|
|
OD_PACKAGED_E2E_WIN: "1"
|
|
OD_PACKAGED_E2E_NAMESPACE: release-stable-win
|
|
OD_PACKAGED_E2E_RELEASE_CHANNEL: ${{ needs.metadata.outputs.channel }}
|
|
OD_PACKAGED_E2E_RELEASE_VERSION: ${{ needs.metadata.outputs.release_version }}
|
|
OD_PACKAGED_E2E_REPORT_DIR: ${{ runner.temp }}/release-report/win
|
|
OD_PACKAGED_E2E_TOOLS_PACK_DIR: ${{ runner.temp }}/tools-pack
|
|
run: |
|
|
$ErrorActionPreference = "Stop"
|
|
pnpm exec tsx scripts/release-smoke.ts win specs/win.spec.ts
|
|
if ($LASTEXITCODE -ne 0) {
|
|
exit $LASTEXITCODE
|
|
}
|
|
|
|
- name: Upload windows e2e spec report
|
|
if: ${{ always() }}
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: open-design-release-win-e2e-report
|
|
path: ${{ runner.temp }}/release-report/win
|
|
if-no-files-found: warn
|
|
|
|
- name: Prune Windows tools-pack cache
|
|
shell: pwsh
|
|
continue-on-error: true
|
|
run: ./.github/scripts/release/cache/win.ps1
|
|
|
|
- name: Save Windows tools-pack cache
|
|
if: ${{ success() && (steps.win_tools_pack_cache_restore.outputs.cache-hit != 'true' || steps.win_tools_pack_build.outputs.cache_failed == 'true') }}
|
|
uses: actions/cache/save@v5
|
|
continue-on-error: true
|
|
with:
|
|
path: ${{ runner.temp }}/tools-pack-cache
|
|
key: ${{ steps.win_tools_pack_cache_key.outputs.key }}
|
|
|
|
- name: Retain recent Windows tools-pack caches
|
|
if: ${{ success() }}
|
|
shell: pwsh
|
|
continue-on-error: true
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
run: |
|
|
$prefix = "${{ steps.win_tools_pack_cache_key.outputs.prefix }}"
|
|
$keep = 3
|
|
$caches = @(gh cache list --key $prefix --sort created_at --order desc --limit 100 --json id,key,createdAt | ConvertFrom-Json)
|
|
$stale = @($caches | Select-Object -Skip $keep)
|
|
foreach ($cache in $stale) {
|
|
gh cache delete $cache.id
|
|
}
|
|
"actionsCachePrefix=$prefix kept=$([Math]::Min($caches.Count, $keep)) deleted=$($stale.Count)"
|
|
|
|
- name: Prepare windows release assets
|
|
shell: pwsh
|
|
env:
|
|
CLOUDFLARE_R2_RELEASES_PUBLIC_ORIGIN: ${{ vars.CLOUDFLARE_R2_RELEASES_PUBLIC_ORIGIN }}
|
|
RELEASE_CHANNEL: ${{ needs.metadata.outputs.channel }}
|
|
RELEASE_NOTES: Open Design ${{ needs.metadata.outputs.release_version }}
|
|
RELEASE_VERSION: ${{ needs.metadata.outputs.release_version }}
|
|
TOOLS_PACK_NAMESPACE: release-stable-win
|
|
run: ./.github/scripts/release/assets/win.ps1
|
|
|
|
- name: Upload windows release bundle
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: open-design-release-win-release-assets
|
|
path: ${{ runner.temp }}/release-assets
|
|
|
|
build_linux:
|
|
name: Build release linux x64
|
|
needs: [metadata, verify]
|
|
# Linux AppImage packaging is temporarily excluded from stable releases.
|
|
# Keep the job definition in place so the Linux lane can be re-enabled once
|
|
# the containerized pnpm bootstrap is fixed and reviewed.
|
|
if: ${{ vars.ENABLE_STABLE_LINUX == 'true' }}
|
|
runs-on: ubuntu-latest
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v6.0.2
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Setup pnpm
|
|
uses: pnpm/action-setup@v5
|
|
with:
|
|
version: 10.33.2
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v6
|
|
with:
|
|
node-version: 24
|
|
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
# `--containerized` builds the AppImage inside the electronuserland/builder
|
|
# Docker image (glibc 2.27 baseline) so the resulting binary runs on older
|
|
# distros than ubuntu-latest's glibc 2.39. Docker is preinstalled on the
|
|
# GitHub-hosted ubuntu-latest runner, so no extra setup is required.
|
|
- name: Build release linux artifacts
|
|
run: |
|
|
set -euo pipefail
|
|
tools_pack_dir="$RUNNER_TEMP/tools-pack"
|
|
report_dir="$RUNNER_TEMP/release-report/linux"
|
|
build_json_path="$report_dir/tools-pack.json"
|
|
build_log_path="$report_dir/tools-pack.log"
|
|
rm -rf "$tools_pack_dir"
|
|
mkdir -p "$report_dir"
|
|
: > "$build_log_path"
|
|
build_args=(
|
|
exec tools-pack linux build
|
|
--dir "$tools_pack_dir"
|
|
--namespace release-stable-linux
|
|
--portable
|
|
--app-version "${{ needs.metadata.outputs.release_version }}"
|
|
--to appimage
|
|
--containerized
|
|
--json
|
|
)
|
|
if build_output="$(pnpm "${build_args[@]}" 2> >(tee -a "$build_log_path" >&2))"; then
|
|
printf '%s\n' "$build_output" | tee "$build_json_path"
|
|
node -e 'const fs = require("node:fs"); JSON.parse(fs.readFileSync(process.argv[1], "utf8"));' "$build_json_path"
|
|
else
|
|
build_status=$?
|
|
printf '%s\n' "$build_output" | tee "$build_json_path"
|
|
exit "$build_status"
|
|
fi
|
|
|
|
- name: Smoke release linux AppImage runtime
|
|
working-directory: e2e
|
|
env:
|
|
OD_PACKAGED_E2E_LINUX_APPIMAGE: "1"
|
|
OD_PACKAGED_E2E_NAMESPACE: release-stable-linux
|
|
OD_PACKAGED_E2E_SCREENSHOT_PATH: ${{ runner.temp }}/release-report/linux/screenshots/open-design-linux-smoke.png
|
|
OD_PACKAGED_E2E_TOOLS_PACK_DIR: ${{ runner.temp }}/tools-pack
|
|
run: |
|
|
set -euo pipefail
|
|
report_dir="$RUNNER_TEMP/release-report/linux"
|
|
mkdir -p "$report_dir/screenshots"
|
|
cat > "$report_dir/manifest.json" <<EOF
|
|
{
|
|
"channel": "${{ needs.metadata.outputs.channel }}",
|
|
"platform": "linux",
|
|
"releaseVersion": "${{ needs.metadata.outputs.release_version }}",
|
|
"spec": "specs/linux.spec.ts",
|
|
"namespace": "release-stable-linux",
|
|
"screenshot": "screenshots/open-design-linux-smoke.png",
|
|
"githubRunId": "$GITHUB_RUN_ID",
|
|
"githubRunAttempt": "$GITHUB_RUN_ATTEMPT",
|
|
"commit": "$GITHUB_SHA"
|
|
}
|
|
EOF
|
|
sudo apt-get update 2>&1 | tee "$report_dir/apt-get-update.log"
|
|
sudo apt-get install -y xvfb 2>&1 | tee "$report_dir/apt-get-install-xvfb.log"
|
|
xvfb-run -a pnpm test specs/linux.spec.ts 2>&1 | tee "$report_dir/vitest.log"
|
|
|
|
- name: Upload linux e2e spec report
|
|
if: ${{ always() }}
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: open-design-release-linux-e2e-report
|
|
path: ${{ runner.temp }}/release-report/linux
|
|
if-no-files-found: warn
|
|
|
|
- name: Prepare linux release assets
|
|
env:
|
|
RELEASE_VERSION: ${{ needs.metadata.outputs.release_version }}
|
|
TOOLS_PACK_NAMESPACE: release-stable-linux
|
|
run: bash .github/scripts/release/assets/linux.sh
|
|
|
|
- name: Upload linux release bundle
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: open-design-release-linux-release-assets
|
|
path: ${{ runner.temp }}/release-assets
|
|
|
|
publish:
|
|
name: Publish ${{ needs.metadata.outputs.channel }} release
|
|
needs:
|
|
- metadata
|
|
- verify
|
|
- build_mac
|
|
- build_mac_intel
|
|
- build_win
|
|
- build_linux
|
|
if: >-
|
|
${{
|
|
always() &&
|
|
!cancelled() &&
|
|
needs.metadata.result == 'success' &&
|
|
needs.verify.result == 'success' &&
|
|
needs.build_mac.result == 'success' &&
|
|
needs.build_mac_intel.result == 'success' &&
|
|
needs.build_win.result == 'success' &&
|
|
(needs.build_linux.result == 'success' || needs.build_linux.result == 'skipped')
|
|
}}
|
|
runs-on: ubuntu-latest
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
AWS_ACCESS_KEY_ID: ${{ secrets.CLOUDFLARE_R2_RELEASES_AK }}
|
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.CLOUDFLARE_R2_RELEASES_SK }}
|
|
AWS_DEFAULT_REGION: auto
|
|
AWS_EC2_METADATA_DISABLED: "true"
|
|
CLOUDFLARE_R2_RELEASES_BUCKET: ${{ secrets.CLOUDFLARE_R2_RELEASES_BUCKET }}
|
|
CLOUDFLARE_R2_RELEASES_PUBLIC_ORIGIN: ${{ vars.CLOUDFLARE_R2_RELEASES_PUBLIC_ORIGIN }}
|
|
CLOUDFLARE_R2_RELEASES_URL: ${{ secrets.CLOUDFLARE_R2_RELEASES_URL }}
|
|
BASE_VERSION: ${{ needs.metadata.outputs.base_version }}
|
|
BRANCH_NAME: ${{ needs.metadata.outputs.branch }}
|
|
ENABLE_LINUX: ${{ needs.build_linux.result == 'success' }}
|
|
ENABLE_MAC: "true"
|
|
ENABLE_MAC_INTEL: "true"
|
|
ENABLE_WIN: "true"
|
|
GITHUB_RELEASE_ENABLED: ${{ needs.metadata.outputs.github_release_enabled }}
|
|
MAC_INTEL_SIGNED: "true"
|
|
NIGHTLY_NUMBER: ${{ needs.metadata.outputs.nightly_number }}
|
|
RELEASE_CHANNEL: ${{ needs.metadata.outputs.channel }}
|
|
RELEASE_NAME: ${{ needs.metadata.outputs.release_name }}
|
|
RELEASE_SIGNED: "true"
|
|
RELEASE_VERSION: ${{ needs.metadata.outputs.release_version }}
|
|
REPORT_MODE: zip
|
|
STATE_SOURCE: ${{ needs.metadata.outputs.state_source }}
|
|
VERSION_TAG: ${{ needs.metadata.outputs.version_tag }}
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v6.0.2
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v6
|
|
with:
|
|
node-version: 24
|
|
|
|
- name: Pre-flight tag/release check
|
|
if: ${{ needs.metadata.outputs.github_release_enabled == 'true' }}
|
|
run: |
|
|
set -euo pipefail
|
|
if git ls-remote --exit-code --tags origin "refs/tags/$VERSION_TAG" >/dev/null 2>&1; then
|
|
echo "tag $VERSION_TAG already exists on origin; aborting" >&2
|
|
exit 1
|
|
fi
|
|
if gh release view "$VERSION_TAG" >/dev/null 2>&1; then
|
|
echo "release $VERSION_TAG already exists; aborting" >&2
|
|
exit 1
|
|
fi
|
|
|
|
- name: Download mac release bundle
|
|
uses: actions/download-artifact@v8
|
|
with:
|
|
name: open-design-release-mac-release-assets
|
|
path: ${{ runner.temp }}/release-assets/mac
|
|
|
|
- name: Download mac intel release bundle
|
|
uses: actions/download-artifact@v8
|
|
with:
|
|
name: open-design-release-mac-intel-release-assets
|
|
path: ${{ runner.temp }}/release-assets/mac-intel
|
|
|
|
- name: Download windows release bundle
|
|
uses: actions/download-artifact@v8
|
|
with:
|
|
name: open-design-release-win-release-assets
|
|
path: ${{ runner.temp }}/release-assets/win
|
|
|
|
- name: Download linux release bundle
|
|
if: ${{ needs.build_linux.result == 'success' }}
|
|
uses: actions/download-artifact@v8
|
|
with:
|
|
name: open-design-release-linux-release-assets
|
|
path: ${{ runner.temp }}/release-assets/linux
|
|
|
|
- name: Download linux e2e spec report
|
|
if: ${{ needs.build_linux.result == 'success' }}
|
|
uses: actions/download-artifact@v8
|
|
with:
|
|
name: open-design-release-linux-e2e-report
|
|
path: ${{ runner.temp }}/release-report/linux
|
|
|
|
- name: Download mac e2e spec report
|
|
uses: actions/download-artifact@v8
|
|
with:
|
|
name: open-design-release-mac-e2e-report
|
|
path: ${{ runner.temp }}/release-report/mac
|
|
|
|
- name: Download windows e2e spec report
|
|
uses: actions/download-artifact@v8
|
|
with:
|
|
name: open-design-release-win-e2e-report
|
|
path: ${{ runner.temp }}/release-report/win
|
|
|
|
- name: Write stable release notes
|
|
id: notes
|
|
if: ${{ needs.metadata.outputs.github_release_enabled == 'true' }}
|
|
run: bash .github/scripts/release/github/stable-notes.sh
|
|
|
|
- name: Create draft release with tag
|
|
id: create_release
|
|
if: ${{ needs.metadata.outputs.github_release_enabled == 'true' }}
|
|
run: |
|
|
set -euo pipefail
|
|
# gh release create creates the tag at $GITHUB_SHA atomically with the release.
|
|
# Using --draft keeps the release invisible until R2 publish and asset upload verify successfully.
|
|
gh release create "$VERSION_TAG" \
|
|
--target "$GITHUB_SHA" \
|
|
--title "$RELEASE_NAME" \
|
|
--notes-file "${{ steps.notes.outputs.notes_file }}" \
|
|
--draft
|
|
|
|
- name: Upload assets to draft release
|
|
if: ${{ needs.metadata.outputs.github_release_enabled == 'true' }}
|
|
run: |
|
|
set -euo pipefail
|
|
all_release_dir="$RUNNER_TEMP/release-assets/all"
|
|
mkdir -p "$all_release_dir"
|
|
cp "$RUNNER_TEMP/release-assets/mac"/* "$all_release_dir/"
|
|
cp "$RUNNER_TEMP/release-assets/mac-intel"/* "$all_release_dir/"
|
|
cp "$RUNNER_TEMP/release-assets/win"/* "$all_release_dir/"
|
|
if [ "$ENABLE_LINUX" = "true" ]; then
|
|
cp "$RUNNER_TEMP/release-assets/linux"/* "$all_release_dir/"
|
|
fi
|
|
gh release upload "$VERSION_TAG" "$all_release_dir"/*
|
|
|
|
- name: Publish release assets and metadata to R2
|
|
id: r2
|
|
run: bash .github/scripts/release/r2/publish.sh
|
|
|
|
- name: Verify R2 release publish
|
|
env:
|
|
R2_LINUX_APPIMAGE_URL: ${{ steps.r2.outputs.linux_appimage_url }}
|
|
R2_MAC_DMG_URL: ${{ steps.r2.outputs.mac_dmg_url }}
|
|
R2_MAC_FEED_URL: ${{ steps.r2.outputs.mac_feed_url }}
|
|
R2_MAC_INTEL_DMG_URL: ${{ steps.r2.outputs.mac_intel_dmg_url }}
|
|
R2_MAC_INTEL_ZIP_URL: ${{ steps.r2.outputs.mac_intel_zip_url }}
|
|
R2_MAC_ZIP_URL: ${{ steps.r2.outputs.mac_zip_url }}
|
|
R2_METADATA_URL: ${{ steps.r2.outputs.metadata_url }}
|
|
R2_REPORT_ZIP_URL: ${{ steps.r2.outputs.report_zip_url }}
|
|
R2_WIN_FEED_URL: ${{ steps.r2.outputs.win_feed_url }}
|
|
R2_WIN_INSTALLER_URL: ${{ steps.r2.outputs.win_installer_url }}
|
|
run: bash .github/scripts/release/r2/verify.sh
|
|
|
|
- name: Promote draft to published latest
|
|
if: ${{ needs.metadata.outputs.github_release_enabled == 'true' }}
|
|
run: |
|
|
set -euo pipefail
|
|
gh release edit "$VERSION_TAG" \
|
|
--draft=false \
|
|
--latest
|
|
|
|
- name: Cleanup release + tag on failure
|
|
if: ${{ failure() && needs.metadata.outputs.github_release_enabled == 'true' && steps.create_release.outcome == 'success' }}
|
|
run: |
|
|
set +e
|
|
echo "publish failed after release was created; rolling back release and tag"
|
|
gh release delete "$VERSION_TAG" --cleanup-tag --yes
|
|
# belt-and-suspenders: ensure remote tag is gone even if --cleanup-tag missed
|
|
git push origin --delete "refs/tags/$VERSION_TAG" || true
|
|
|
|
- name: Publish summary
|
|
env:
|
|
R2_LINUX_APPIMAGE_URL: ${{ steps.r2.outputs.linux_appimage_url }}
|
|
R2_MAC_DMG_URL: ${{ steps.r2.outputs.mac_dmg_url }}
|
|
R2_MAC_FEED_URL: ${{ steps.r2.outputs.mac_feed_url }}
|
|
R2_MAC_INTEL_DMG_URL: ${{ steps.r2.outputs.mac_intel_dmg_url }}
|
|
R2_MAC_INTEL_ZIP_URL: ${{ steps.r2.outputs.mac_intel_zip_url }}
|
|
R2_MAC_ZIP_URL: ${{ steps.r2.outputs.mac_zip_url }}
|
|
R2_METADATA_URL: ${{ steps.r2.outputs.metadata_url }}
|
|
R2_REPORT_ZIP_URL: ${{ steps.r2.outputs.report_zip_url }}
|
|
R2_VERSION_METADATA_URL: ${{ steps.r2.outputs.version_metadata_url }}
|
|
R2_VERSION_PREFIX: ${{ steps.r2.outputs.version_prefix }}
|
|
R2_WIN_FEED_URL: ${{ steps.r2.outputs.win_feed_url }}
|
|
R2_WIN_INSTALLER_URL: ${{ steps.r2.outputs.win_installer_url }}
|
|
run: bash .github/scripts/release/r2/summary.sh
|
|
|
|
- name: Cleanup workflow artifacts
|
|
if: ${{ success() }}
|
|
run: bash .github/scripts/release/github/cleanup-artifacts.sh
|