chore: prune unused apps and services for the moeka fork
CI / Lint (push) Canceled after 0s
CI / Build Test (stage-web) (push) Canceled after 0s
CI / Build Test (ui-loading-screens) (push) Canceled after 0s
CI / Build Test (ui-transitions) (push) Canceled after 0s
CI / Unit Test (push) Canceled after 0s
CI / Type Check (push) Canceled after 0s
CI / Check Provenance (push) Canceled after 0s
Sync Labels / sync-labels (push) Successful in 1m43s
CI / Lint (push) Canceled after 0s
CI / Build Test (stage-web) (push) Canceled after 0s
CI / Build Test (ui-loading-screens) (push) Canceled after 0s
CI / Build Test (ui-transitions) (push) Canceled after 0s
CI / Unit Test (push) Canceled after 0s
CI / Type Check (push) Canceled after 0s
CI / Check Provenance (push) Canceled after 0s
Sync Labels / sync-labels (push) Successful in 1m43s
- Remove stage-tamagotchi, stage-pocket, server, and engine workspaces with their workflows, addons, and docs - Switch the toolchain from pnpm to bun, replace lockfiles with bun.lock - Rewrite remaining product references to Moeka
This commit is contained in:
@@ -16,20 +16,20 @@ jobs:
|
||||
- uses: actions/checkout@v6
|
||||
# NOTICE:
|
||||
# Pin Node.js because 26.8.0 reports 26.8.0-alpha.0.0.0.
|
||||
# sharp 0.29.3 rejects this prerelease version during pnpm install.
|
||||
# sharp 0.29.3 rejects this prerelease version during bun install.
|
||||
# Source: https://github.com/nodejs/node/blob/v26.8.0/src/node_version.h
|
||||
# Remove this pin when Node.js 26 reports a stable version.
|
||||
- uses: pnpm/setup@v2
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
runtime: node@26.7.0
|
||||
cache: true
|
||||
install: false
|
||||
node-version: 26.7.0
|
||||
|
||||
- run: pnpm install
|
||||
- run: pnpm prune && pnpm dedupe
|
||||
- run: pnpm run lint:fix
|
||||
- run: docker run -v `pwd`:`pwd` -w `pwd` ghcr.io/realm/swiftlint:latest --fix
|
||||
working-directory: ./apps/stage-pocket
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version: 1.4.2
|
||||
|
||||
- run: bun install
|
||||
- run: bun prune && bun dedupe
|
||||
- run: bun run lint:fix
|
||||
|
||||
# - name: AutoCorrect
|
||||
# uses: huacnlee/autocorrect-action@main
|
||||
|
||||
+33
-84
@@ -18,33 +18,19 @@ jobs:
|
||||
- uses: actions/checkout@v6
|
||||
# NOTICE:
|
||||
# Pin Node.js because 26.8.0 reports 26.8.0-alpha.0.0.0.
|
||||
# sharp 0.29.3 rejects this prerelease version during pnpm install.
|
||||
# sharp 0.29.3 rejects this prerelease version during bun install.
|
||||
# Source: https://github.com/nodejs/node/blob/v26.8.0/src/node_version.h
|
||||
# Remove this pin when Node.js 26 reports a stable version.
|
||||
- uses: pnpm/setup@v2
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
runtime: node@26.7.0
|
||||
cache: true
|
||||
install: false
|
||||
node-version: 26.7.0
|
||||
|
||||
# Setup .NET for Godot C# linting
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
dotnet-version: '10.0.x'
|
||||
bun-version: 1.4.2
|
||||
|
||||
# Lint Godot C# code
|
||||
- name: Lint Godot C#
|
||||
working-directory: ./engines/stage-tamagotchi-godot
|
||||
run: dotnet format stage-tamagotchi-godot.slnx --verify-no-changes
|
||||
|
||||
- run: docker run -v `pwd`:`pwd` -w `pwd` ghcr.io/realm/swiftlint:latest
|
||||
working-directory: ./apps/stage-pocket
|
||||
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- run: pnpm run lint
|
||||
- run: docker run -v `pwd`:`pwd` -w `pwd` ghcr.io/realm/swiftlint:latest
|
||||
working-directory: ./apps/stage-pocket
|
||||
- run: bun install --frozen-lockfile
|
||||
- run: bun run lint
|
||||
|
||||
build-test:
|
||||
name: Build Test (${{ matrix.app_name }})
|
||||
@@ -53,19 +39,13 @@ jobs:
|
||||
matrix:
|
||||
include:
|
||||
- app_name: stage-web
|
||||
command: pnpm -F @proj-airi/stage-web run build && pnpm -F @proj-airi/docs run build:base && mv ./docs/.vitepress/dist ./apps/stage-web/dist/docs && pnpm -F @proj-airi/stage-ui run story:build && mv ./packages/stage-ui/.histoire/dist ./apps/stage-web/dist/ui
|
||||
|
||||
- app_name: stage-tamagotchi
|
||||
command: pnpm -F @proj-airi/stage-tamagotchi run build
|
||||
|
||||
- app_name: stage-tamagotchi-godot
|
||||
command: cd engines/stage-tamagotchi-godot && dotnet restore && dotnet build -c ExportRelease
|
||||
command: bun run --filter @proj-airi/stage-web build && bun run --filter @proj-airi/docs build:base && mv ./docs/.vitepress/dist ./apps/stage-web/dist/docs && bun run --filter @proj-airi/stage-ui story:build && mv ./packages/stage-ui/.histoire/dist ./apps/stage-web/dist/ui
|
||||
|
||||
- app_name: ui-transitions
|
||||
command: pnpm -F @proj-airi/ui-transitions run play:build
|
||||
command: bun run --filter @proj-airi/ui-transitions play:build
|
||||
|
||||
- app_name: ui-loading-screens
|
||||
command: pnpm -F @proj-airi/ui-loading-screens run play:build
|
||||
command: bun run --filter @proj-airi/ui-loading-screens play:build
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -80,40 +60,20 @@ jobs:
|
||||
restore-keys: |
|
||||
${{ runner.os }}-turbo-
|
||||
|
||||
- uses: pnpm/setup@v2
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
runtime: node@26.7.0
|
||||
cache: true
|
||||
install: false
|
||||
node-version: 26.7.0
|
||||
|
||||
# Setup .NET and Godot
|
||||
- name: Setup .NET
|
||||
if: matrix.app_name == 'stage-tamagotchi-godot'
|
||||
uses: actions/setup-dotnet@v4
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
dotnet-version: '10.0.x'
|
||||
bun-version: 1.4.2
|
||||
|
||||
- name: Setup Godot
|
||||
if: matrix.app_name == 'stage-tamagotchi-godot'
|
||||
uses: chickensoft-games/setup-godot@v2
|
||||
with:
|
||||
version: 4.7.1
|
||||
use-dotnet: true
|
||||
include-templates: true
|
||||
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- run: pnpm run build:packages
|
||||
- run: bun install --frozen-lockfile
|
||||
- run: bun run build:packages
|
||||
|
||||
- name: Build App
|
||||
run: ${{ matrix.command }}
|
||||
|
||||
- name: Export Godot Linux sidecar
|
||||
if: matrix.app_name == 'stage-tamagotchi-godot'
|
||||
working-directory: ./engines/stage-tamagotchi-godot
|
||||
run: |
|
||||
mkdir -p out/linux
|
||||
godot --headless --export-release "Linux x64" out/linux/godot-stage
|
||||
|
||||
unit-test:
|
||||
name: Unit Test
|
||||
runs-on: ubuntu-latest
|
||||
@@ -129,34 +89,21 @@ jobs:
|
||||
restore-keys: |
|
||||
${{ runner.os }}-turbo-
|
||||
|
||||
- uses: pnpm/setup@v2
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
runtime: node@26.7.0
|
||||
cache: true
|
||||
install: false
|
||||
node-version: 26.7.0
|
||||
|
||||
# # Setup .NET and Godot
|
||||
# - name: Setup .NET
|
||||
# if: matrix.app_name == 'stage-tamagotchi-godot'
|
||||
# uses: actions/setup-dotnet@v4
|
||||
# with:
|
||||
# dotnet-version: '10.0.x'
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version: 1.4.2
|
||||
|
||||
# - name: Setup Godot
|
||||
# if: matrix.app_name == 'stage-tamagotchi-godot'
|
||||
# uses: chickensoft-games/setup-godot@v2
|
||||
# with:
|
||||
# version: 4.7.1
|
||||
# use-dotnet: true
|
||||
# include-templates: true
|
||||
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- run: bun install --frozen-lockfile
|
||||
|
||||
- name: Setup Playwright
|
||||
run: npx playwright install chromium
|
||||
|
||||
- run: pnpm run build:packages
|
||||
- run: pnpm run test:run
|
||||
- run: bun run build:packages
|
||||
- run: bun run test:run
|
||||
env:
|
||||
NODE_OPTIONS: --no-experimental-webstorage
|
||||
|
||||
@@ -168,14 +115,16 @@ jobs:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
# Node.js
|
||||
- uses: pnpm/setup@v2
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
runtime: node@26.7.0
|
||||
cache: true
|
||||
install: false
|
||||
node-version: 26.7.0
|
||||
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- run: pnpm run typecheck
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version: 1.4.2
|
||||
|
||||
- run: bun install --frozen-lockfile
|
||||
- run: bun run typecheck
|
||||
|
||||
check-provenance:
|
||||
name: Check Provenance
|
||||
@@ -188,7 +137,7 @@ jobs:
|
||||
id: check
|
||||
with:
|
||||
fail-on-provenance-change: true # optional, default: false
|
||||
# lockfile: pnpm-lock.yaml # optional
|
||||
# lockfile: bun.lock # optional
|
||||
# base-ref: origin/main # optional, default: origin/main
|
||||
# fail-on-downgrade: true # optional, default: true
|
||||
- name: Print result
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
name: Cloudflare Pages (Auth UI)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
name: Deploy - ui-server-auth
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
deployments: write
|
||||
|
||||
environment:
|
||||
name: Auth Production
|
||||
url: https://accounts.airi.build/ui/
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
# Turborepo
|
||||
- name: Cache turbo build setup
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: .turbo
|
||||
key: ${{ runner.os }}-turbo-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-turbo-
|
||||
- uses: pnpm/setup@v2
|
||||
with:
|
||||
runtime: node@26.7.0
|
||||
cache: true
|
||||
install: false
|
||||
# NOTICE:
|
||||
#
|
||||
# Keep the wrangler setup consistent with the stage-web deployment
|
||||
# workflow. cloudflare/wrangler-action expects a usable wrangler binary
|
||||
# when running repository-local pnpm workspaces.
|
||||
- run: pnpm i -g wrangler@4
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- run: pnpm run build:packages
|
||||
- name: Build ui-server-auth
|
||||
run: pnpm -F @proj-airi/ui-server-auth run build
|
||||
env:
|
||||
VITE_ENABLE_ANALYTICS: 'true'
|
||||
VITE_SERVER_URL: 'https://api.airi.build'
|
||||
|
||||
- uses: cloudflare/wrangler-action@v4
|
||||
with:
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
command: pages deploy ./apps/ui-server-auth/dist --project-name=airi-accounts-ui --branch=main
|
||||
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -1,132 +0,0 @@
|
||||
name: Cloudflare Workers (server-dev)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'server-dev'
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
deploy-stage-web:
|
||||
name: Deploy - stage-web (server-dev)
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
deployments: write
|
||||
|
||||
environment:
|
||||
name: ServerDev
|
||||
url: ${{ steps.preview-urls.outputs.preview_url }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
# Turborepo
|
||||
- name: Cache turbo build setup
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: .turbo
|
||||
key: ${{ runner.os }}-turbo-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-turbo-
|
||||
- uses: pnpm/setup@v2
|
||||
with:
|
||||
runtime: node@26.7.0
|
||||
cache: true
|
||||
install: false
|
||||
- run: pnpm i -g wrangler@4
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- run: pnpm run build:packages
|
||||
- name: Build stage-web
|
||||
run: |
|
||||
pnpm -F @proj-airi/stage-web run build
|
||||
|
||||
pnpm -F @proj-airi/docs run build:base
|
||||
mv ./docs/.vitepress/dist ./apps/stage-web/dist/docs
|
||||
cp ./apps/stage-web/dist/docs/sitemap.xml ./apps/stage-web/dist/sitemap.xml
|
||||
|
||||
pnpm -F @proj-airi/stage-ui run story:build
|
||||
mv ./packages/stage-ui/.histoire/dist ./apps/stage-web/dist/ui
|
||||
env:
|
||||
S3_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY_ID }}
|
||||
S3_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_ACCESS_KEY }}
|
||||
S3_ENDPOINT: ${{ secrets.S3_ENDPOINT }}
|
||||
S3_REGION: ${{ secrets.S3_REGION }}
|
||||
WARP_DRIVE_PUBLIC_BASE: ${{ secrets.WARP_DRIVE_PUBLIC_BASE }}
|
||||
VITE_SERVER_URL: 'https://airi-server-dev.up.railway.app'
|
||||
|
||||
- name: Wrangler Upload
|
||||
id: wrangler-versions-upload
|
||||
uses: cloudflare/wrangler-action@v4
|
||||
with:
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
command: versions upload -c ./apps/stage-web/wrangler.toml --preview-alias server-dev --message "GitHub Actions uploaded server-dev branch preview" --tag v0.0.1-server-dev
|
||||
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Prepare preview URL
|
||||
id: preview-urls
|
||||
run: |
|
||||
deployment_url="${{ steps.wrangler-versions-upload.outputs.deployment-url }}"
|
||||
if [ -z "$deployment_url" ]; then
|
||||
echo "Deployment URL from wrangler upload is empty." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
host_without_scheme="${deployment_url#https://}"
|
||||
host_without_scheme="${host_without_scheme#http://}"
|
||||
preview_url="https://server-dev-${host_without_scheme#*-}"
|
||||
|
||||
echo "preview_url=$preview_url" >> "$GITHUB_OUTPUT"
|
||||
echo "Preview URL: $preview_url"
|
||||
|
||||
deploy-auth-ui:
|
||||
name: Deploy - ui-server-auth (server-dev)
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
deployments: write
|
||||
|
||||
environment:
|
||||
name: AuthServerDev
|
||||
url: https://server-dev.airi-server-auth.pages.dev/ui/
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
# Turborepo
|
||||
- name: Cache turbo build setup
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: .turbo
|
||||
key: ${{ runner.os }}-turbo-auth-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-turbo-auth-
|
||||
${{ runner.os }}-turbo-
|
||||
- uses: pnpm/setup@v2
|
||||
with:
|
||||
runtime: node@26.7.0
|
||||
cache: true
|
||||
install: false
|
||||
- run: pnpm i -g wrangler@4
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- run: pnpm run build:packages
|
||||
- name: Build ui-server-auth
|
||||
run: pnpm -F @proj-airi/ui-server-auth run build
|
||||
env:
|
||||
VITE_SERVER_URL: 'https://airi-server-dev.up.railway.app'
|
||||
|
||||
- name: Wrangler Pages Deploy
|
||||
uses: cloudflare/wrangler-action@v4
|
||||
with:
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
command: pages deploy ./apps/ui-server-auth/dist --project-name=airi-accounts-ui --branch=server-dev
|
||||
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Print preview URL
|
||||
run: |
|
||||
echo "Preview URL: https://server-dev.airi-server-auth.pages.dev/ui/"
|
||||
@@ -1,260 +0,0 @@
|
||||
name: Cloudflare Workers (Preview) Deploy
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows:
|
||||
- Cloudflare Workers (Preview) Prepare
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
ask-for-approval:
|
||||
name: Ask for approval to deploy - ${{ matrix.app_name }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: write
|
||||
contents: read
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- app_name: stage-web
|
||||
|
||||
steps:
|
||||
- name: Download artifact - metadata
|
||||
uses: dawidd6/action-download-artifact@v19
|
||||
with:
|
||||
workflow_conclusion: success
|
||||
run_id: ${{ github.event.workflow_run.id }}
|
||||
name: preview-meta
|
||||
path: preview-meta
|
||||
allow_forks: true
|
||||
|
||||
- name: Parse metadata
|
||||
id: meta
|
||||
run: |
|
||||
node --input-type=module <<'NODE'
|
||||
import { appendFile, readFile } from 'node:fs/promises'
|
||||
|
||||
const metadata = JSON.parse(await readFile('preview-meta/preview-meta.json', 'utf8'))
|
||||
if (
|
||||
!/^\d+$/.test(metadata.prNumber)
|
||||
|| !/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(metadata.repositoryFullName)
|
||||
|| !/^[a-f0-9]{40}$/i.test(metadata.headSha)
|
||||
) {
|
||||
throw new Error('Preview metadata has an invalid shape')
|
||||
}
|
||||
|
||||
await appendFile(process.env.GITHUB_OUTPUT, [
|
||||
`PR_NUM=${metadata.prNumber}`,
|
||||
`REPO_FULL_NAME=${metadata.repositoryFullName}`,
|
||||
`HEAD_SHA=${metadata.headSha}`,
|
||||
'',
|
||||
].join('\n'))
|
||||
NODE
|
||||
|
||||
- name: Find Comment
|
||||
if: ${{ always() }}
|
||||
uses: peter-evans/find-comment@v4
|
||||
id: fc
|
||||
with:
|
||||
issue-number: ${{ steps.meta.outputs.PR_NUM }}
|
||||
comment-author: 'github-actions[bot]'
|
||||
body-includes: to Cloudflare Workers (Preview) for *${{ matrix.app_name }}*
|
||||
|
||||
- name: Comment on require approval
|
||||
uses: peter-evans/create-or-update-comment@v5
|
||||
with:
|
||||
comment-id: ${{ steps.fc.outputs.comment-id }}
|
||||
issue-number: ${{ steps.meta.outputs.PR_NUM }}
|
||||
edit-mode: replace
|
||||
body: |
|
||||
## ⏳ Approval required for deploying to Cloudflare Workers (Preview) for *${{ matrix.app_name }}*.
|
||||
|
||||
| Name | Link |
|
||||
|:------------------------|:---------------------------------------------------------------------------------------|
|
||||
| 🔭 Waiting for approval | For maintainers, approve [here](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
|
||||
|
||||
Hey, maintainers, kindly take some time to review and approve this deployment when you are available. Thank you! 🙏
|
||||
|
||||
on-success:
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
name: Deploy - ${{ matrix.app_name }}
|
||||
runs-on: ubuntu-latest
|
||||
environment: Preview
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- app_name: stage-web
|
||||
wrangler_config_path: ./apps/stage-web/wrangler.toml
|
||||
build_directory: ./apps/stage-web/dist
|
||||
build_command: |
|
||||
pnpm -F @proj-airi/stage-web run build
|
||||
|
||||
pnpm -F @proj-airi/docs run build:base
|
||||
mv ./docs/.vitepress/dist ./apps/stage-web/dist/docs
|
||||
cp ./apps/stage-web/dist/docs/sitemap.xml ./apps/stage-web/dist/sitemap.xml
|
||||
|
||||
pnpm -F @proj-airi/stage-ui run story:build
|
||||
mv ./packages/stage-ui/.histoire/dist ./apps/stage-web/dist/ui
|
||||
|
||||
steps:
|
||||
- name: Download artifact - metadata
|
||||
uses: dawidd6/action-download-artifact@v19
|
||||
with:
|
||||
workflow_conclusion: success
|
||||
run_id: ${{ github.event.workflow_run.id }}
|
||||
name: preview-meta
|
||||
path: preview-meta
|
||||
allow_forks: true
|
||||
|
||||
- name: Parse metadata
|
||||
id: meta
|
||||
run: |
|
||||
node --input-type=module <<'NODE'
|
||||
import { appendFile, readFile } from 'node:fs/promises'
|
||||
|
||||
const metadata = JSON.parse(await readFile('preview-meta/preview-meta.json', 'utf8'))
|
||||
if (
|
||||
!/^\d+$/.test(metadata.prNumber)
|
||||
|| !/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(metadata.repositoryFullName)
|
||||
|| !/^[a-f0-9]{40}$/i.test(metadata.headSha)
|
||||
) {
|
||||
throw new Error('Preview metadata has an invalid shape')
|
||||
}
|
||||
|
||||
await appendFile(process.env.GITHUB_OUTPUT, [
|
||||
`PR_NUM=${metadata.prNumber}`,
|
||||
`REPO_FULL_NAME=${metadata.repositoryFullName}`,
|
||||
`HEAD_SHA=${metadata.headSha}`,
|
||||
'',
|
||||
].join('\n'))
|
||||
NODE
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
repository: ${{ steps.meta.outputs.REPO_FULL_NAME }}
|
||||
ref: ${{ steps.meta.outputs.HEAD_SHA }}
|
||||
fetch-depth: 1
|
||||
persist-credentials: false
|
||||
# https://gh.io/securely-using-pull_request_target
|
||||
allow-unsafe-pr-checkout: true
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/setup@v2
|
||||
with:
|
||||
runtime: node@26.7.0
|
||||
cache: true
|
||||
install: false
|
||||
|
||||
# NOTICE:
|
||||
#
|
||||
# Here installing wrangler to global is required, or otherwise:
|
||||
# ERR_PNPM_ADDING_TO_ROOT Running this command will add the dependency to the workspace root...
|
||||
# error occurs.
|
||||
#
|
||||
# Since https://github.com/cloudflare/wrangler-action/pull/339#issuecomment-2667622947 rejected the -g support
|
||||
# by saying un-reasonable 'I'm not sure if it's common ... to install packages to the global scope, ... might be introducing some unintended side effects.'
|
||||
#
|
||||
# Clearly I think installing with `<packageManager> install` brings more unintended side effects...
|
||||
#
|
||||
# As suggested by https://github.com/cloudflare/wrangler-action/issues/181#issuecomment-2127990708, we should pre-install
|
||||
# with our package manager and then use it in the action.
|
||||
- run: pnpm i -g wrangler@4
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build packages
|
||||
run: pnpm run build:packages
|
||||
|
||||
- name: Build ${{ matrix.app_name }}
|
||||
id: build
|
||||
run: ${{ matrix.build_command }}
|
||||
continue-on-error: true
|
||||
env:
|
||||
S3_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY_ID }}
|
||||
S3_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_ACCESS_KEY }}
|
||||
S3_ENDPOINT: ${{ secrets.S3_ENDPOINT }}
|
||||
S3_REGION: ${{ secrets.S3_REGION }}
|
||||
WARP_DRIVE_PUBLIC_BASE: ${{ secrets.WARP_DRIVE_PUBLIC_BASE }}
|
||||
STAGE_WEB_WARP_DRIVE_PREFIX: proj-airi/stage-web/pr-${{ steps.meta.outputs.PR_NUM }}/
|
||||
STAGE_UI_WARP_DRIVE_PREFIX: proj-airi/stage-ui/pr-${{ steps.meta.outputs.PR_NUM }}/
|
||||
|
||||
- name: Find Comment
|
||||
if: ${{ always() }}
|
||||
uses: peter-evans/find-comment@v4
|
||||
id: fc
|
||||
with:
|
||||
issue-number: ${{ steps.meta.outputs.PR_NUM }}
|
||||
comment-author: 'github-actions[bot]'
|
||||
body-includes: to Cloudflare Workers (Preview) for *${{ matrix.app_name }}*
|
||||
|
||||
- name: Comment on build failure
|
||||
if: ${{ steps.build.outcome != 'success' }}
|
||||
uses: peter-evans/create-or-update-comment@v5
|
||||
with:
|
||||
comment-id: ${{ steps.fc.outputs.comment-id }}
|
||||
issue-number: ${{ steps.meta.outputs.PR_NUM }}
|
||||
edit-mode: replace
|
||||
body: |
|
||||
## ❌ Deploy to Cloudflare Workers (Preview) for *${{ matrix.app_name }}* failed.
|
||||
|
||||
| Name | Link |
|
||||
|:---------------------|:---------------------------------------------------------------------------------------|
|
||||
| 🔍 Latest deploy log | https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} |
|
||||
|
||||
- name: Fail if build failed
|
||||
if: ${{ steps.build.outcome != 'success' }}
|
||||
run: |
|
||||
echo "Build step failed; marking workflow as failed."
|
||||
exit 1
|
||||
|
||||
- name: Wrangler Upload
|
||||
if: ${{ steps.build.outcome == 'success' }}
|
||||
id: wrangler-versions-upload
|
||||
uses: cloudflare/wrangler-action@v4
|
||||
with:
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
command: versions upload -c ${{ matrix.wrangler_config_path }} --preview-alias pr-${{ steps.meta.outputs.PR_NUM }} --message "GitHub Actions uploaded preview for Pull Request ${{ steps.meta.outputs.PR_NUM }}" --tag v0.0.1-pr.${{ steps.meta.outputs.PR_NUM }}
|
||||
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Prepare preview URLs
|
||||
if: ${{ steps.build.outcome == 'success' }}
|
||||
id: preview-urls
|
||||
run: |
|
||||
deployment_url="${{ steps.wrangler-versions-upload.outputs.deployment-url }}"
|
||||
if [ -z "$deployment_url" ]; then
|
||||
echo "Deployment URL from wrangler upload is empty." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
host_without_scheme="${deployment_url#https://}"
|
||||
host_without_scheme="${host_without_scheme#http://}"
|
||||
preview_alias_url="https://pr-${{ steps.meta.outputs.PR_NUM }}-${host_without_scheme#*-}"
|
||||
|
||||
echo "deploy_preview_url=$deployment_url" >> "$GITHUB_OUTPUT"
|
||||
echo "pull_request_preview_url=$preview_alias_url" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Create or update comment
|
||||
if: ${{ steps.build.outcome == 'success' }}
|
||||
uses: peter-evans/create-or-update-comment@v5
|
||||
with:
|
||||
comment-id: ${{ steps.fc.outputs.comment-id }}
|
||||
issue-number: ${{ steps.meta.outputs.PR_NUM }}
|
||||
edit-mode: replace
|
||||
body: |
|
||||
## ✅ Deploy to Cloudflare Workers (Preview) for *${{ matrix.app_name }}* ready!
|
||||
|
||||
| Name | Link |
|
||||
|:------------------------|:--------------------------------------------------------------------------------------------|
|
||||
| 🔍 Latest deploy log | https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} |
|
||||
| 😎 Deploy Preview | ${{ steps.preview-urls.outputs.deploy_preview_url }} |
|
||||
| 🚀 Pull Request Preview | ${{ steps.preview-urls.outputs.pull_request_preview_url }} |
|
||||
@@ -1,37 +0,0 @@
|
||||
name: Cloudflare Workers (Preview) Prepare
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
prepare:
|
||||
name: Prepare preview sources
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Persist checkout metadata
|
||||
env:
|
||||
PR_NUM: ${{ github.event.number }}
|
||||
REPO_FULL_NAME: ${{ github.event.pull_request.head.repo.full_name }}
|
||||
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
|
||||
run: |
|
||||
node --input-type=module <<'NODE'
|
||||
import { writeFile } from 'node:fs/promises'
|
||||
|
||||
await writeFile('preview-meta.json', JSON.stringify({
|
||||
prNumber: process.env.PR_NUM,
|
||||
repositoryFullName: process.env.REPO_FULL_NAME,
|
||||
headSha: process.env.HEAD_SHA,
|
||||
}))
|
||||
NODE
|
||||
|
||||
- name: Upload metadata artifact
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: preview-meta
|
||||
path: ./preview-meta.json
|
||||
overwrite: true
|
||||
@@ -1,81 +0,0 @@
|
||||
name: Cloudflare Workers
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
name: Deploy - stage-web
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
deployments: write
|
||||
|
||||
environment:
|
||||
name: Production
|
||||
url: https://airi.moeru.ai/docs/
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
# Turborepo
|
||||
- name: Cache turbo build setup
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: .turbo
|
||||
key: ${{ runner.os }}-turbo-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-turbo-
|
||||
- uses: pnpm/setup@v2
|
||||
with:
|
||||
runtime: node@26.7.0
|
||||
cache: true
|
||||
install: false
|
||||
# NOTICE:
|
||||
#
|
||||
# Here installing wrangler to global is required, or otherwise:
|
||||
# ERR_PNPM_ADDING_TO_ROOT Running this command will add the dependency to the workspace root...
|
||||
# error occurs.
|
||||
#
|
||||
# Since https://github.com/cloudflare/wrangler-action/pull/339#issuecomment-2667622947 rejected the -g support
|
||||
# by saying un-reasonable 'I'm not sure if it's common ... to install packages to the global scope, ... might be introducing some unintended side effects.'
|
||||
#
|
||||
# Clearly I think installing with `<packageManager> install` brings more unintended side effects...
|
||||
#
|
||||
# As suggested by https://github.com/cloudflare/wrangler-action/issues/181#issuecomment-2127990708, we should pre-install
|
||||
# with our package manager and then use it in the action.
|
||||
- run: pnpm i -g wrangler@4
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- run: pnpm run build:packages
|
||||
- name: Build stage-web
|
||||
run: |
|
||||
pnpm -F @proj-airi/stage-web run build
|
||||
|
||||
pnpm -F @proj-airi/docs run build:base
|
||||
mv ./docs/.vitepress/dist ./apps/stage-web/dist/docs
|
||||
cp ./apps/stage-web/dist/docs/sitemap.xml ./apps/stage-web/dist/sitemap.xml
|
||||
|
||||
pnpm -F @proj-airi/stage-ui run story:build
|
||||
mv ./packages/stage-ui/.histoire/dist ./apps/stage-web/dist/ui
|
||||
env:
|
||||
S3_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY_ID }}
|
||||
S3_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_ACCESS_KEY }}
|
||||
S3_ENDPOINT: ${{ secrets.S3_ENDPOINT }}
|
||||
S3_REGION: ${{ secrets.S3_REGION }}
|
||||
VITE_ENABLE_ANALYTICS: 'true'
|
||||
VITE_SERVER_URL: 'https://api.airi.build'
|
||||
WARP_DRIVE_PUBLIC_BASE: ${{ secrets.WARP_DRIVE_PUBLIC_BASE }}
|
||||
|
||||
- uses: cloudflare/wrangler-action@v4
|
||||
with:
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
command: deploy -c ./apps/stage-web/wrangler.toml
|
||||
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -22,14 +22,16 @@ jobs:
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN }}
|
||||
HF_USERNAME: ${{ secrets.HF_USERNAME }}
|
||||
|
||||
- uses: pnpm/setup@v2
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
runtime: node@26.7.0
|
||||
cache: true
|
||||
install: false
|
||||
node-version: 26.7.0
|
||||
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- run: pnpm build
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version: 1.4.2
|
||||
|
||||
- run: bun install --frozen-lockfile
|
||||
- run: bun run build
|
||||
env:
|
||||
TARGET_HUGGINGFACE_SPACE: 'true'
|
||||
VITE_APP_TARGET_HUGGINGFACE_SPACE: 'true'
|
||||
|
||||
Generated
+4
-4
@@ -351,15 +351,15 @@ jobs:
|
||||
mkdir -p /tmp/gh-aw/safeoutputs
|
||||
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
|
||||
cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_7cd577a1928d35f4_EOF'
|
||||
{"add_labels":{"allowed":["bug","feature","pending triage","apps/stage-pocket","apps/stage-tamagotchi","apps/stage-web","env/os-all","env/os-linux","env/os-macos","env/os-windows","priority/general","priority/nice-to-have","priority/urgent","scope/agent","scope/audio-input","scope/audio-output","scope/avatar","scope/avatar/live2d","scope/avatar/vrm","scope/documentation","scope/engineering","scope/extension","scope/game-playing-ai","scope/i18n","scope/providers","scope/server-api","scope/ui"],"max":12,"target":"${{ github.event.pull_request.number || github.event.inputs.pull_request_number }}"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"remove_labels":{"allowed":["bug","feature","pending triage","apps/stage-pocket","apps/stage-tamagotchi","apps/stage-web","env/os-all","env/os-linux","env/os-macos","env/os-windows","priority/general","priority/nice-to-have","priority/urgent","scope/agent","scope/audio-input","scope/audio-output","scope/avatar","scope/avatar/live2d","scope/avatar/vrm","scope/documentation","scope/engineering","scope/extension","scope/game-playing-ai","scope/i18n","scope/providers","scope/server-api","scope/ui"],"max":24,"target":"${{ github.event.pull_request.number || github.event.inputs.pull_request_number }}"},"report_incomplete":{}}
|
||||
{"add_labels":{"allowed":["bug","feature","pending triage","apps/stage-web","env/os-all","env/os-linux","env/os-macos","env/os-windows","priority/general","priority/nice-to-have","priority/urgent","scope/agent","scope/audio-input","scope/audio-output","scope/avatar","scope/avatar/live2d","scope/avatar/vrm","scope/documentation","scope/engineering","scope/extension","scope/game-playing-ai","scope/i18n","scope/providers","scope/server-api","scope/ui"],"max":12,"target":"${{ github.event.pull_request.number || github.event.inputs.pull_request_number }}"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"remove_labels":{"allowed":["bug","feature","pending triage","apps/stage-web","env/os-all","env/os-linux","env/os-macos","env/os-windows","priority/general","priority/nice-to-have","priority/urgent","scope/agent","scope/audio-input","scope/audio-output","scope/avatar","scope/avatar/live2d","scope/avatar/vrm","scope/documentation","scope/engineering","scope/extension","scope/game-playing-ai","scope/i18n","scope/providers","scope/server-api","scope/ui"],"max":24,"target":"${{ github.event.pull_request.number || github.event.inputs.pull_request_number }}"},"report_incomplete":{}}
|
||||
GH_AW_SAFE_OUTPUTS_CONFIG_7cd577a1928d35f4_EOF
|
||||
- name: Write Safe Outputs Tools
|
||||
env:
|
||||
GH_AW_TOOLS_META_JSON: |
|
||||
{
|
||||
"description_suffixes": {
|
||||
"add_labels": " CONSTRAINTS: Maximum 12 label(s) can be added. Only these labels are allowed: [\"bug\" \"feature\" \"pending triage\" \"apps/stage-pocket\" \"apps/stage-tamagotchi\" \"apps/stage-web\" \"env/os-all\" \"env/os-linux\" \"env/os-macos\" \"env/os-windows\" \"priority/general\" \"priority/nice-to-have\" \"priority/urgent\" \"scope/agent\" \"scope/audio-input\" \"scope/audio-output\" \"scope/avatar\" \"scope/avatar/live2d\" \"scope/avatar/vrm\" \"scope/documentation\" \"scope/engineering\" \"scope/extension\" \"scope/game-playing-ai\" \"scope/i18n\" \"scope/providers\" \"scope/server-api\" \"scope/ui\"]. Target: ${{ github.event.pull_request.number || github.event.inputs.pull_request_number }}.",
|
||||
"remove_labels": " CONSTRAINTS: Maximum 24 label(s) can be removed. Only these labels can be removed: [bug feature pending triage apps/stage-pocket apps/stage-tamagotchi apps/stage-web env/os-all env/os-linux env/os-macos env/os-windows priority/general priority/nice-to-have priority/urgent scope/agent scope/audio-input scope/audio-output scope/avatar scope/avatar/live2d scope/avatar/vrm scope/documentation scope/engineering scope/extension scope/game-playing-ai scope/i18n scope/providers scope/server-api scope/ui]. Target: ${{ github.event.pull_request.number || github.event.inputs.pull_request_number }}."
|
||||
"add_labels": " CONSTRAINTS: Maximum 12 label(s) can be added. Only these labels are allowed: [\"bug\" \"feature\" \"pending triage\" \"apps/stage-web\" \"env/os-all\" \"env/os-linux\" \"env/os-macos\" \"env/os-windows\" \"priority/general\" \"priority/nice-to-have\" \"priority/urgent\" \"scope/agent\" \"scope/audio-input\" \"scope/audio-output\" \"scope/avatar\" \"scope/avatar/live2d\" \"scope/avatar/vrm\" \"scope/documentation\" \"scope/engineering\" \"scope/extension\" \"scope/game-playing-ai\" \"scope/i18n\" \"scope/providers\" \"scope/server-api\" \"scope/ui\"]. Target: ${{ github.event.pull_request.number || github.event.inputs.pull_request_number }}.",
|
||||
"remove_labels": " CONSTRAINTS: Maximum 24 label(s) can be removed. Only these labels can be removed: [bug feature pending triage apps/stage-web env/os-all env/os-linux env/os-macos env/os-windows priority/general priority/nice-to-have priority/urgent scope/agent scope/audio-input scope/audio-output scope/avatar scope/avatar/live2d scope/avatar/vrm scope/documentation scope/engineering scope/extension scope/game-playing-ai scope/i18n scope/providers scope/server-api scope/ui]. Target: ${{ github.event.pull_request.number || github.event.inputs.pull_request_number }}."
|
||||
},
|
||||
"repo_params": {},
|
||||
"dynamic_tools": []
|
||||
@@ -1112,7 +1112,7 @@ jobs:
|
||||
GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
|
||||
GITHUB_SERVER_URL: ${{ github.server_url }}
|
||||
GITHUB_API_URL: ${{ github.api_url }}
|
||||
GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_labels\":{\"allowed\":[\"bug\",\"feature\",\"pending triage\",\"apps/stage-pocket\",\"apps/stage-tamagotchi\",\"apps/stage-web\",\"env/os-all\",\"env/os-linux\",\"env/os-macos\",\"env/os-windows\",\"priority/general\",\"priority/nice-to-have\",\"priority/urgent\",\"scope/agent\",\"scope/audio-input\",\"scope/audio-output\",\"scope/avatar\",\"scope/avatar/live2d\",\"scope/avatar/vrm\",\"scope/documentation\",\"scope/engineering\",\"scope/extension\",\"scope/game-playing-ai\",\"scope/i18n\",\"scope/providers\",\"scope/server-api\",\"scope/ui\"],\"max\":12,\"target\":\"${{ github.event.pull_request.number || github.event.inputs.pull_request_number }}\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"remove_labels\":{\"allowed\":[\"bug\",\"feature\",\"pending triage\",\"apps/stage-pocket\",\"apps/stage-tamagotchi\",\"apps/stage-web\",\"env/os-all\",\"env/os-linux\",\"env/os-macos\",\"env/os-windows\",\"priority/general\",\"priority/nice-to-have\",\"priority/urgent\",\"scope/agent\",\"scope/audio-input\",\"scope/audio-output\",\"scope/avatar\",\"scope/avatar/live2d\",\"scope/avatar/vrm\",\"scope/documentation\",\"scope/engineering\",\"scope/extension\",\"scope/game-playing-ai\",\"scope/i18n\",\"scope/providers\",\"scope/server-api\",\"scope/ui\"],\"max\":24,\"target\":\"${{ github.event.pull_request.number || github.event.inputs.pull_request_number }}\"},\"report_incomplete\":{}}"
|
||||
GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_labels\":{\"allowed\":[\"bug\",\"feature\",\"pending triage\",\"apps/stage-web\",\"env/os-all\",\"env/os-linux\",\"env/os-macos\",\"env/os-windows\",\"priority/general\",\"priority/nice-to-have\",\"priority/urgent\",\"scope/agent\",\"scope/audio-input\",\"scope/audio-output\",\"scope/avatar\",\"scope/avatar/live2d\",\"scope/avatar/vrm\",\"scope/documentation\",\"scope/engineering\",\"scope/extension\",\"scope/game-playing-ai\",\"scope/i18n\",\"scope/providers\",\"scope/server-api\",\"scope/ui\"],\"max\":12,\"target\":\"${{ github.event.pull_request.number || github.event.inputs.pull_request_number }}\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"remove_labels\":{\"allowed\":[\"bug\",\"feature\",\"pending triage\",\"apps/stage-web\",\"env/os-all\",\"env/os-linux\",\"env/os-macos\",\"env/os-windows\",\"priority/general\",\"priority/nice-to-have\",\"priority/urgent\",\"scope/agent\",\"scope/audio-input\",\"scope/audio-output\",\"scope/avatar\",\"scope/avatar/live2d\",\"scope/avatar/vrm\",\"scope/documentation\",\"scope/engineering\",\"scope/extension\",\"scope/game-playing-ai\",\"scope/i18n\",\"scope/providers\",\"scope/server-api\",\"scope/ui\"],\"max\":24,\"target\":\"${{ github.event.pull_request.number || github.event.inputs.pull_request_number }}\"},\"report_incomplete\":{}}"
|
||||
with:
|
||||
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
|
||||
@@ -33,8 +33,6 @@ safe-outputs:
|
||||
- bug
|
||||
- feature
|
||||
- pending triage
|
||||
- apps/stage-pocket
|
||||
- apps/stage-tamagotchi
|
||||
- apps/stage-web
|
||||
- env/os-all
|
||||
- env/os-linux
|
||||
@@ -64,8 +62,6 @@ safe-outputs:
|
||||
- bug
|
||||
- feature
|
||||
- pending triage
|
||||
- apps/stage-pocket
|
||||
- apps/stage-tamagotchi
|
||||
- apps/stage-web
|
||||
- env/os-all
|
||||
- env/os-linux
|
||||
@@ -105,7 +101,7 @@ The target pull request is:
|
||||
Managed labels:
|
||||
|
||||
- Type: `bug`, `feature`
|
||||
- App surface: `apps/stage-pocket`, `apps/stage-tamagotchi`, `apps/stage-web`
|
||||
- App surface: `apps/stage-web`
|
||||
- Environment: `env/os-all`, `env/os-linux`, `env/os-macos`, `env/os-windows`
|
||||
- Scope: `scope/agent`, `scope/audio-input`, `scope/audio-output`, `scope/avatar`, `scope/avatar/live2d`, `scope/avatar/vrm`, `scope/documentation`, `scope/engineering`, `scope/extension`, `scope/game-playing-ai`, `scope/i18n`, `scope/providers`, `scope/server-api`, `scope/ui`
|
||||
- Priority: `priority/general`, `priority/nice-to-have`, `priority/urgent`
|
||||
@@ -160,9 +156,7 @@ Do not use web search. Do not use bash to modify files, create branches, post co
|
||||
### App labels
|
||||
|
||||
- Apply `apps/stage-web` when files under `apps/stage-web/` change, or the PR text explicitly says the change is for the web app or PWA/browser surface.
|
||||
- Apply `apps/stage-tamagotchi` when files under `apps/stage-tamagotchi/` change, or the PR text explicitly says desktop/Electron/Windows/macOS/Linux app.
|
||||
- Apply `apps/stage-pocket` when files under `apps/stage-pocket/` change, or the PR text explicitly says mobile/iOS/Android app.
|
||||
- Multiple app labels are allowed when the evidence is explicit.
|
||||
- Only `apps/stage-web` exists in this fork. Never apply a desktop or mobile app label.
|
||||
|
||||
### Environment labels
|
||||
|
||||
|
||||
@@ -21,11 +21,13 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: pnpm/setup@v2
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
runtime: node@26.7.0
|
||||
cache: true
|
||||
install: false
|
||||
node-version: 26.7.0
|
||||
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version: 1.4.2
|
||||
|
||||
- name: Configure npm registry
|
||||
uses: actions/setup-node@v6
|
||||
@@ -39,9 +41,9 @@ jobs:
|
||||
# https://github.com/e18e/ecosystem-issues/issues/201
|
||||
- run: npm install -g npm@latest
|
||||
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- run: pnpm run build:packages
|
||||
- run: bun install --frozen-lockfile
|
||||
- run: bun run build:packages
|
||||
|
||||
- run: pnpm publish -r --access public --no-git-checks --dry-run
|
||||
- run: bun run publish:packages -- --dry-run
|
||||
|
||||
- run: pnpm publish -r --access public --no-git-checks
|
||||
- run: bun run publish:packages
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
name: Release Pocket (Android)
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
actions: read
|
||||
|
||||
on:
|
||||
release:
|
||||
types:
|
||||
- prereleased
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
build_only:
|
||||
description: Build only (no upload to release)
|
||||
required: false
|
||||
default: false
|
||||
type: boolean
|
||||
tag:
|
||||
description: Specific tag for the release upload
|
||||
required: false
|
||||
type: string
|
||||
schedule:
|
||||
- cron: '0 1 * * *'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build Android APK
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
PRODUCT_NAME: 'AIRI'
|
||||
# Every current trigger path produces an installable APK artifact, so ship the analytics-enabled build consistently.
|
||||
VITE_ENABLE_ANALYTICS: 'true'
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: '21'
|
||||
|
||||
- name: Setup Android SDK
|
||||
uses: android-actions/setup-android@v3
|
||||
|
||||
- uses: pnpm/setup@v2
|
||||
with:
|
||||
runtime: node@26.7.0
|
||||
cache: true
|
||||
install: false
|
||||
|
||||
- name: Install Android build tools
|
||||
run: |
|
||||
sdkmanager "build-tools;36.1.0"
|
||||
echo "${ANDROID_SDK_ROOT:-$ANDROID_HOME}/build-tools/36.1.0" >> "$GITHUB_PATH"
|
||||
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- run: pnpm run build:packages
|
||||
|
||||
- name: Validate workflow dispatch release tag
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && !inputs.build_only && inputs.tag == '' }}
|
||||
run: |
|
||||
echo "workflow_dispatch release uploads require the tag input"
|
||||
exit 1
|
||||
|
||||
- name: Build web assets
|
||||
run: pnpm -F @proj-airi/stage-pocket run build
|
||||
|
||||
- name: Capacitor sync
|
||||
run: pnpm -F @proj-airi/stage-pocket exec cap sync android
|
||||
|
||||
- name: Extract android keystore
|
||||
run: echo "${{ secrets.CAPACITOR_ANDROID_KEYSTORE_BASE64 }}" | base64 -d > ${{ github.workspace }}/apps/stage-pocket/airi-pocket.jks
|
||||
|
||||
- name: Build APK
|
||||
working-directory: apps/stage-pocket/android
|
||||
run: pnpm -F @proj-airi/stage-pocket exec cap build android
|
||||
env:
|
||||
CAPACITOR_ANDROID_KEYSTORE_PATH: ${{ github.workspace }}/apps/stage-pocket/airi-pocket.jks
|
||||
CAPACITOR_ANDROID_KEYSTORE_ALIAS: ${{ secrets.CAPACITOR_ANDROID_KEYSTORE_ALIAS }}
|
||||
CAPACITOR_ANDROID_KEYSTORE_PASSWORD: ${{ secrets.CAPACITOR_ANDROID_KEYSTORE_PASSWORD }}
|
||||
CAPACITOR_ANDROID_KEYSTORE_ALIAS_PASSWORD: ${{ secrets.CAPACITOR_ANDROID_KEYSTORE_ALIAS_PASSWORD }}
|
||||
|
||||
- name: Rename APK for distribution
|
||||
env:
|
||||
RELEASE_TAG_NAME: ${{ github.event.release.tag_name || inputs.tag }}
|
||||
run: |
|
||||
VERSION="${RELEASE_TAG_NAME#v}"
|
||||
if [ -z "$VERSION" ]; then
|
||||
VERSION="$(sed -n 's/^AIRI_VERSION_NAME=//p' apps/stage-pocket/android/app-version.properties)"
|
||||
fi
|
||||
|
||||
APK_NAME="${PRODUCT_NAME}-${VERSION}-android.apk"
|
||||
APK_SOURCE="apps/stage-pocket/android/app/build/outputs/apk/release/app-release-signed.apk"
|
||||
APK_BUNDLE_DIR="apps/stage-pocket/android/bundle"
|
||||
|
||||
mkdir -p "$APK_BUNDLE_DIR"
|
||||
mv "$APK_SOURCE" "$APK_BUNDLE_DIR/$APK_NAME"
|
||||
|
||||
echo "APK_NAME=$APK_NAME" >> "$GITHUB_ENV"
|
||||
echo "VERSION=$VERSION" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Upload APK artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.APK_NAME }}
|
||||
path: apps/stage-pocket/android/bundle/${{ env.APK_NAME }}
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload to GitHub Releases
|
||||
id: upload-github-release
|
||||
if: ${{ github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && !inputs.build_only) }}
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: apps/stage-pocket/android/bundle/${{ env.APK_NAME }}
|
||||
append_body: true
|
||||
tag_name: ${{ github.event.release.tag_name || inputs.tag }}
|
||||
|
||||
- name: Setup butler
|
||||
uses: remarkablegames/setup-butler@v2
|
||||
|
||||
# https://itch.io/docs/butler/pushing.html
|
||||
- name: Upload Android to itch.io
|
||||
if: ${{ github.event_name == 'release' }}
|
||||
run: butler push apps/stage-pocket/android/bundle/${{ env.APK_NAME }} nekomeowww/airi:android --userversion ${{ env.VERSION }}
|
||||
env:
|
||||
BUTLER_API_KEY: ${{ secrets.GAME_PUBLISHING_ITCHIO }}
|
||||
|
||||
- name: Publish release assets to GitCode
|
||||
if: ${{ always() && github.repository == 'moeru-ai/airi' && steps.upload-github-release.outcome == 'success' && (github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && !inputs.build_only)) }}
|
||||
continue-on-error: true
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITCODE_TOKEN: ${{ secrets.GITCODE_TOKEN }}
|
||||
GITCODE_OWNER: ${{ secrets.GITCODE_OWNER }}
|
||||
GITCODE_REPO: ${{ secrets.GITCODE_REPO }}
|
||||
GITCODE_RELEASE_TAG: ${{ github.event.release.tag_name || inputs.tag }}
|
||||
run: bash .github/scripts/publish-gitcode-release.sh
|
||||
@@ -1,180 +0,0 @@
|
||||
name: Release Pocket (iOS)
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
actions: read
|
||||
|
||||
on:
|
||||
release:
|
||||
types:
|
||||
- prereleased
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
testflight:
|
||||
description: Upload to TestFlight
|
||||
type: boolean
|
||||
default: false
|
||||
tag:
|
||||
description: GitHub Release tag (empty to skip)
|
||||
type: string
|
||||
required: false
|
||||
default: ''
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build iOS
|
||||
runs-on: macos-26
|
||||
env:
|
||||
PRODUCT_NAME: 'AIRI'
|
||||
VITE_ENABLE_ANALYTICS: 'true'
|
||||
UPLOAD_TESTFLIGHT: ${{ github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.testflight) }}
|
||||
RELEASE_TAG: ${{ github.event.release.tag_name || inputs.tag }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: pnpm/setup@v2
|
||||
with:
|
||||
runtime: node@26.7.0
|
||||
cache: true
|
||||
install: false
|
||||
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- run: pnpm run build:packages
|
||||
|
||||
- name: Build assets
|
||||
run: pnpm -F @proj-airi/stage-pocket run build
|
||||
|
||||
- name: Sync assets to iOS
|
||||
run: pnpm -F @proj-airi/stage-pocket exec cap sync ios
|
||||
|
||||
- name: Install Apple certificate
|
||||
env:
|
||||
CERT_BASE64: ${{ secrets.APPLE_DISTRIBUTION_CERT_BASE64 }}
|
||||
CERT_PASSWORD: ${{ secrets.APPLE_DISTRIBUTION_CERT_PASSWORD }}
|
||||
run: |
|
||||
CERT_PATH="$RUNNER_TEMP/certificate.p12"
|
||||
KEYCHAIN_PATH="$RUNNER_TEMP/app-signing.keychain-db"
|
||||
KEYCHAIN_PASSWORD="$(openssl rand -hex 16)"
|
||||
|
||||
echo "$CERT_BASE64" | base64 --decode -o "$CERT_PATH"
|
||||
|
||||
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
|
||||
security set-keychain-settings -lut 3600 "$KEYCHAIN_PATH"
|
||||
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
|
||||
|
||||
security import "$CERT_PATH" -k "$KEYCHAIN_PATH" -P "$CERT_PASSWORD" \
|
||||
-T /usr/bin/codesign -T /usr/bin/security
|
||||
|
||||
security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
|
||||
security list-keychains -d user -s "$KEYCHAIN_PATH" login.keychain-db
|
||||
|
||||
echo "KEYCHAIN_PATH=$KEYCHAIN_PATH" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Install provisioning profile
|
||||
env:
|
||||
PROFILE_BASE64: ${{ secrets.APPLE_PROVISIONING_PROFILE_BASE64 }}
|
||||
run: |
|
||||
PROFILE_PATH="$RUNNER_TEMP/profile.mobileprovision"
|
||||
echo "$PROFILE_BASE64" | base64 --decode -o "$PROFILE_PATH"
|
||||
|
||||
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
|
||||
cp "$PROFILE_PATH" ~/Library/MobileDevice/Provisioning\ Profiles/
|
||||
|
||||
- name: Read version from Xcode project
|
||||
run: |
|
||||
PBXPROJ="apps/stage-pocket/ios/App/App.xcodeproj/project.pbxproj"
|
||||
VERSION="$(sed -n 's/.*MARKETING_VERSION = \(.*\);/\1/p' "$PBXPROJ" | head -1 | tr -d ' ')"
|
||||
BUILD_NUMBER="$(sed -n 's/.*CURRENT_PROJECT_VERSION = \(.*\);/\1/p' "$PBXPROJ" | head -1 | tr -d ' ')"
|
||||
|
||||
echo "VERSION=$VERSION" >> "$GITHUB_ENV"
|
||||
echo "BUILD_NUMBER=$BUILD_NUMBER" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Archive iOS
|
||||
run: |
|
||||
xcodebuild archive \
|
||||
-project apps/stage-pocket/ios/App/App.xcodeproj \
|
||||
-scheme App \
|
||||
-configuration Release \
|
||||
-destination "generic/platform=iOS" \
|
||||
-archivePath "$RUNNER_TEMP/App.xcarchive" \
|
||||
CURRENT_PROJECT_VERSION=${{ env.BUILD_NUMBER }}
|
||||
|
||||
- name: Export IPA
|
||||
run: |
|
||||
xcodebuild -exportArchive \
|
||||
-archivePath "$RUNNER_TEMP/App.xcarchive" \
|
||||
-exportPath "$RUNNER_TEMP/output" \
|
||||
-exportOptionsPlist apps/stage-pocket/ios/ExportOptions.plist
|
||||
|
||||
- name: Rename IPA for distribution
|
||||
run: |
|
||||
IPA_SOURCE="$(find "$RUNNER_TEMP/output" -name '*.ipa' -print -quit)"
|
||||
IPA_NAME="${PRODUCT_NAME}-${VERSION}_(${BUILD_NUMBER})-ios.ipa"
|
||||
|
||||
mv "$IPA_SOURCE" "$RUNNER_TEMP/output/$IPA_NAME"
|
||||
|
||||
echo "IPA_NAME=$IPA_NAME" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Upload IPA artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.IPA_NAME }}
|
||||
path: ${{ runner.temp }}/output/${{ env.IPA_NAME }}
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Install Transporter
|
||||
if: ${{ env.UPLOAD_TESTFLIGHT == 'true' }}
|
||||
run: |
|
||||
curl -fsSL "https://itunesconnect.apple.com/WebObjects/iTunesConnect.woa/ra/resources/download/public/Transporter__OSX/bin/" -o "$RUNNER_TEMP/itmstransporter.pkg"
|
||||
sudo installer -pkg "$RUNNER_TEMP/itmstransporter.pkg" -target /
|
||||
rm -f "$RUNNER_TEMP/itmstransporter.pkg"
|
||||
|
||||
- name: Upload to TestFlight
|
||||
if: ${{ env.UPLOAD_TESTFLIGHT == 'true' }}
|
||||
uses: apple-actions/upload-testflight-build@v4
|
||||
with:
|
||||
app-path: ${{ runner.temp }}/output/${{ env.IPA_NAME }}
|
||||
issuer-id: ${{ secrets.APPSTORE_CONNECT_API_ISSUER_ID }}
|
||||
api-key-id: ${{ secrets.APPSTORE_CONNECT_API_KEY_ID }}
|
||||
api-private-key: ${{ secrets.APPSTORE_CONNECT_API_KEY }}
|
||||
|
||||
- name: Upload to GitHub Releases
|
||||
if: ${{ env.RELEASE_TAG != '' }}
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: ${{ runner.temp }}/output/${{ env.IPA_NAME }}
|
||||
append_body: true
|
||||
fail_on_unmatched_files: true
|
||||
tag_name: ${{ env.RELEASE_TAG }}
|
||||
|
||||
- name: Clean up signing
|
||||
if: always()
|
||||
run: |
|
||||
if [ -n "$KEYCHAIN_PATH" ]; then
|
||||
security delete-keychain "$KEYCHAIN_PATH" 2>/dev/null || true
|
||||
fi
|
||||
rm -f ~/Library/MobileDevice/Provisioning\ Profiles/*.mobileprovision
|
||||
|
||||
publish-gitcode-release:
|
||||
name: Publish GitCode Release Mirror
|
||||
needs: build
|
||||
if: ${{ always() && github.repository == 'moeru-ai/airi' && needs.build.result == 'success' && (github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.tag != '')) }}
|
||||
continue-on-error: true
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Validate release mirror tools
|
||||
run: |
|
||||
gh --version
|
||||
jq --version
|
||||
curl --version
|
||||
|
||||
- name: Publish release assets to GitCode
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITCODE_TOKEN: ${{ secrets.GITCODE_TOKEN }}
|
||||
GITCODE_OWNER: ${{ secrets.GITCODE_OWNER }}
|
||||
GITCODE_REPO: ${{ secrets.GITCODE_REPO }}
|
||||
GITCODE_RELEASE_TAG: ${{ github.event.release.tag_name || inputs.tag }}
|
||||
run: bash .github/scripts/publish-gitcode-release.sh
|
||||
@@ -1,278 +0,0 @@
|
||||
name: Release Tamagotchi to Steam
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
actions: read
|
||||
|
||||
on:
|
||||
release:
|
||||
types:
|
||||
- prereleased
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
upload_to_steam:
|
||||
description: Upload the completed build to Steam
|
||||
required: true
|
||||
default: false
|
||||
type: boolean
|
||||
release_branch:
|
||||
description: Steam branch to set live
|
||||
required: true
|
||||
default: internal-test
|
||||
type: string
|
||||
build_description:
|
||||
description: Optional Steam build description
|
||||
required: false
|
||||
type: string
|
||||
|
||||
concurrency:
|
||||
group: steam-deploy-tamagotchi-${{ github.event_name == 'workflow_dispatch' && inputs.release_branch || 'internal-test' }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build ${{ matrix.depot }} depot
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
VITE_DISTRIBUTION: steam
|
||||
VITE_DISABLE_CUSTOM_PROVIDERS: 'true'
|
||||
VITE_DISABLE_FLUX_PURCHASE: 'true'
|
||||
VITE_ENABLE_ANALYTICS: 'false'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- depot: windows
|
||||
os: windows-latest
|
||||
builder-args: --windows --x64
|
||||
arch: x64
|
||||
|
||||
- depot: macos
|
||||
os: macos-26
|
||||
builder-args: --macos --arm64
|
||||
arch: arm64
|
||||
|
||||
- depot: linux
|
||||
os: ubuntu-latest
|
||||
builder-args: --linux --x64
|
||||
arch: x64
|
||||
|
||||
steps:
|
||||
# The Linux desktop build needs more space than the default hosted runner provides.
|
||||
- name: Free Linux disk space
|
||||
if: matrix.depot == 'linux'
|
||||
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Select Xcode 26.2
|
||||
if: matrix.depot == 'macos'
|
||||
run: |
|
||||
sudo xcode-select -s /Applications/Xcode_26.2.app
|
||||
xcodebuild -version
|
||||
|
||||
- name: Show macOS toolchain
|
||||
if: matrix.depot == 'macos'
|
||||
run: |
|
||||
xcodebuild -version
|
||||
actool --version
|
||||
|
||||
- uses: pnpm/setup@v2
|
||||
with:
|
||||
runtime: node@26.7.0
|
||||
cache: true
|
||||
install: false
|
||||
|
||||
- name: Install macOS system dependencies for node-canvas
|
||||
if: matrix.depot == 'macos'
|
||||
run: brew install pkg-config cairo pango jpeg giflib librsvg
|
||||
|
||||
- run: pnpm install --frozen-lockfile
|
||||
|
||||
- run: pnpm run build:packages
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: '10.0.x'
|
||||
|
||||
- name: Setup Godot
|
||||
uses: chickensoft-games/setup-godot@v2
|
||||
with:
|
||||
version: '4.7.1'
|
||||
use-dotnet: true
|
||||
include-templates: true
|
||||
|
||||
- name: Export Godot Stage for Windows
|
||||
if: matrix.depot == 'windows'
|
||||
working-directory: ./engines/stage-tamagotchi-godot
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p out/win
|
||||
godot --headless --export-release "Windows Desktop" out/win/godot-stage.exe
|
||||
|
||||
- name: Export Godot Stage for macOS
|
||||
if: matrix.depot == 'macos'
|
||||
working-directory: ./engines/stage-tamagotchi-godot
|
||||
run: |
|
||||
mkdir -p out/mac
|
||||
godot --headless --export-release "macOS" out/mac/godot-stage.app
|
||||
|
||||
- name: Clean Godot Stage for Steam on macOS
|
||||
if: matrix.depot == 'macos'
|
||||
working-directory: ./engines/stage-tamagotchi-godot
|
||||
run: |
|
||||
# NOTICE:
|
||||
# SteamPipe excludes *.pdb files after Electron signs the parent app.
|
||||
# Removing Godot debug symbols and AppleDouble files before signing keeps macOS sealed resources aligned with the installed bundle.
|
||||
# Source/context: Steam internal-test BuildID 24160350 and the game-ci SteamPipe FileExclusion "*.pdb" behavior.
|
||||
# Removal condition: SteamPipe preserves these resources or the embedded Godot bundle no longer contains them.
|
||||
find out/mac/godot-stage.app -name '*.pdb' -delete
|
||||
find out/mac/godot-stage.app -name '._*' -delete
|
||||
|
||||
- name: Export Godot Stage for Linux
|
||||
if: matrix.depot == 'linux'
|
||||
working-directory: ./engines/stage-tamagotchi-godot
|
||||
run: |
|
||||
mkdir -p out/linux
|
||||
godot --headless --export-release "Linux ${{ matrix.arch }}" out/linux/godot-stage
|
||||
|
||||
- name: Build Windows app
|
||||
if: matrix.depot == 'windows'
|
||||
run: pnpm run -F @proj-airi/stage-tamagotchi build && pnpm -F @proj-airi/stage-tamagotchi exec electron-builder build ${{ matrix.builder-args }} --publish=never
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build macOS app
|
||||
if: matrix.depot == 'macos'
|
||||
run: |
|
||||
echo "$CSC_CONTENT" | base64 --decode > apps/stage-tamagotchi/apple-developer-code-signing.p12
|
||||
export CSC_LINK="./apple-developer-code-signing.p12"
|
||||
pnpm run -F @proj-airi/stage-tamagotchi build
|
||||
pnpm -F @proj-airi/stage-tamagotchi exec electron-builder build ${{ matrix.builder-args }} --publish=never
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CSC_CONTENT: ${{ secrets.CSC_CONTENT }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
|
||||
APPLE_ID: ${{ secrets.APPLE_DEVELOPER_APPLE_ID }}
|
||||
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_DEVELOPER_APPLE_APP_SPECIFIC_PASSWORD }}
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_DEVELOPER_TEAM_ID }}
|
||||
|
||||
- name: Build Linux app
|
||||
if: matrix.depot == 'linux'
|
||||
run: pnpm run -F @proj-airi/stage-tamagotchi build && pnpm -F @proj-airi/stage-tamagotchi exec electron-builder build ${{ matrix.builder-args }} --publish=never
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Package Windows depot
|
||||
if: matrix.depot == 'windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
New-Item -ItemType Directory -Force steam-content/windows | Out-Null
|
||||
Copy-Item apps/stage-tamagotchi/dist/win-unpacked/* steam-content/windows -Recurse -Force
|
||||
tar -cf steam-content-windows.tar -C steam-content windows
|
||||
|
||||
- name: Package macOS depot
|
||||
if: matrix.depot == 'macos'
|
||||
run: |
|
||||
app_path="apps/stage-tamagotchi/dist/mac-arm64/AIRI.app"
|
||||
if [[ ! -d "$app_path" ]]; then
|
||||
echo "::error::No macOS app bundle was produced."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p steam-content/macos
|
||||
ditto --norsrc "$app_path" steam-content/macos/AIRI.app
|
||||
find steam-content/macos -name '._*' -delete
|
||||
COPYFILE_DISABLE=1 tar -cf steam-content-macos.tar -C steam-content macos
|
||||
|
||||
- name: Package Linux depot
|
||||
if: matrix.depot == 'linux'
|
||||
run: |
|
||||
mkdir -p steam-content/linux
|
||||
cp -a apps/stage-tamagotchi/dist/linux-unpacked/. steam-content/linux/
|
||||
tar -cf steam-content-linux.tar -C steam-content linux
|
||||
|
||||
- name: Upload depot artifact
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: steam-content-${{ matrix.depot }}
|
||||
path: steam-content-${{ matrix.depot }}.tar
|
||||
if-no-files-found: error
|
||||
overwrite: true
|
||||
|
||||
deploy:
|
||||
name: Upload to Steam
|
||||
if: ${{ github.event_name == 'release' || inputs.upload_to_steam }}
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
STEAM_APP_ID: '3885340'
|
||||
STEAM_DEBUG_BRANCH: 'false'
|
||||
STEAM_RELEASE_BRANCH: ${{ github.event_name == 'workflow_dispatch' && inputs.release_branch || 'internal-test' }}
|
||||
STEAM_WINDOWS_DEPOT_ID: '3885342'
|
||||
steps:
|
||||
- name: Validate Steam branch
|
||||
env:
|
||||
RELEASE_BRANCH: ${{ env.STEAM_RELEASE_BRANCH }}
|
||||
run: |
|
||||
if [[ ! "$RELEASE_BRANCH" =~ ^[A-Za-z0-9._-]+$ ]]; then
|
||||
echo "::error::Steam release branch may contain only letters, numbers, dots, underscores, and hyphens."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$RELEASE_BRANCH" == "default" ]]; then
|
||||
echo '::error::Steam release branch "default" must be promoted manually.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Normalize Steam build description
|
||||
id: metadata
|
||||
uses: actions/github-script@v9
|
||||
env:
|
||||
INPUT_BUILD_DESCRIPTION: ${{ inputs.build_description }}
|
||||
RELEASE_TAG: ${{ github.event.release.tag_name }}
|
||||
with:
|
||||
result-encoding: string
|
||||
script: |
|
||||
const source = process.env.RELEASE_TAG || process.env.GITHUB_SHA
|
||||
const fallback = `AIRI ${source} Steam candidate`
|
||||
const normalizedDescription = (process.env.INPUT_BUILD_DESCRIPTION || fallback)
|
||||
.replace(/[\r\n\t]+/g, ' ')
|
||||
.replace(/[\u0000-\u001f\u007f]+/g, ' ')
|
||||
.replaceAll('\\', '/')
|
||||
.replaceAll('"', "'")
|
||||
.replace(/ {2,}/g, ' ')
|
||||
.trim()
|
||||
.slice(0, 512)
|
||||
|
||||
return normalizedDescription || fallback
|
||||
|
||||
- name: Download Steam depots
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
pattern: steam-content-*
|
||||
path: steam-artifacts
|
||||
merge-multiple: true
|
||||
|
||||
- name: Prepare Steam upload root
|
||||
run: |
|
||||
mkdir -p steam-build
|
||||
tar -xf steam-artifacts/steam-content-windows.tar -C steam-build
|
||||
tar -xf steam-artifacts/steam-content-macos.tar -C steam-build
|
||||
tar -xf steam-artifacts/steam-content-linux.tar -C steam-build
|
||||
|
||||
- name: Deploy desktop builds to Steam
|
||||
uses: game-ci/steam-deploy@v3.2.0
|
||||
with:
|
||||
username: ${{ secrets.STEAM_USERNAME }}
|
||||
configVdf: ${{ secrets.STEAM_CONFIG_VDF }}
|
||||
appId: ${{ env.STEAM_APP_ID }}
|
||||
firstDepotIdOverride: ${{ env.STEAM_WINDOWS_DEPOT_ID }}
|
||||
buildDescription: ${{ steps.metadata.outputs.result }}
|
||||
rootPath: steam-build
|
||||
depot1Path: windows
|
||||
depot2Path: macos
|
||||
depot3Path: linux
|
||||
releaseBranch: ${{ env.STEAM_RELEASE_BRANCH }}
|
||||
debugBranch: ${{ env.STEAM_DEBUG_BRANCH }}
|
||||
@@ -1,665 +0,0 @@
|
||||
name: Release Tamagotchi
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
actions: read
|
||||
|
||||
env:
|
||||
BUNDLE_NAME: ''
|
||||
DEB_BUNDLE_NAME: ''
|
||||
RPM_BUNDLE_NAME: ''
|
||||
FLATPAK_BUNDLE_NAME: ''
|
||||
PRODUCT_NAME: 'AIRI'
|
||||
VERSION: ''
|
||||
|
||||
on:
|
||||
release:
|
||||
types:
|
||||
- prereleased
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
build_only:
|
||||
description: Build only
|
||||
required: false
|
||||
default: false
|
||||
type: boolean
|
||||
artifacts_only:
|
||||
description: Build and upload artifacts only
|
||||
required: false
|
||||
default: false
|
||||
type: boolean
|
||||
tag:
|
||||
description: Specific tag/commit for the release (leave empty to auto-detect latest tag)
|
||||
required: false
|
||||
type: string
|
||||
platform:
|
||||
description: Platform
|
||||
type: choice
|
||||
options:
|
||||
- all
|
||||
- windows
|
||||
- macos
|
||||
- linux
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
continue-on-error: ${{ matrix.skip }} # WORKAROUND: Skipping subsequent steps without failing the whole workflow
|
||||
env:
|
||||
VITE_ENABLE_ANALYTICS: ${{ ((github.event_name == 'release') || (github.event_name == 'workflow_dispatch' && !inputs.build_only)) && 'true' || 'false' }}
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
|
||||
- os: macos-15-intel
|
||||
artifact: darwin-x64
|
||||
target: x86_64-apple-darwin
|
||||
arch: x64
|
||||
builder-args: --macos --x64
|
||||
skip: ${{ inputs.platform != '' && inputs.platform != 'all' && inputs.platform != 'macos' }}
|
||||
|
||||
- os: macos-26
|
||||
artifact: darwin-arm64
|
||||
target: aarch64-apple-darwin
|
||||
builder-args: --macos --arm64
|
||||
arch: arm64
|
||||
skip: ${{ inputs.platform != '' && inputs.platform != 'all' && inputs.platform != 'macos' }}
|
||||
|
||||
- os: ubuntu-latest
|
||||
artifact: linux-x64
|
||||
target: x86_64-unknown-linux-gnu
|
||||
builder-args: --linux --x64
|
||||
arch: x64
|
||||
skip: ${{ inputs.platform != '' && inputs.platform != 'all' && inputs.platform != 'linux' }}
|
||||
|
||||
- os: ubuntu-24.04-arm
|
||||
artifact: linux-arm64
|
||||
target: aarch64-unknown-linux-gnu
|
||||
builder-args: --linux --arm64
|
||||
arch: arm64
|
||||
skip: ${{ inputs.platform != '' && inputs.platform != 'all' && inputs.platform != 'linux' }}
|
||||
|
||||
- os: windows-latest
|
||||
artifact: windows-x64-setup
|
||||
target: x86_64-pc-windows-msvc
|
||||
builder-args: --windows --x64
|
||||
arch: x64
|
||||
skip: ${{ inputs.platform != '' && inputs.platform != 'all' && inputs.platform != 'windows' }}
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Skip the build (fail fast)
|
||||
run: |
|
||||
echo "Skipping build for ${{ matrix.os }}..."
|
||||
echo "This will fail the job, but don't panic—this is expected when not building for all."
|
||||
echo "This will be improved in the future."
|
||||
exit ${{ matrix.skip && '1' || '0' }}
|
||||
|
||||
# Why?
|
||||
#
|
||||
# failed to build archive at `/home/runner/work/airi/airi/target/x86_64-unknown-linux-gnu/release/deps/libapp_lib.rlib`:
|
||||
# No space left on device (os error 28)
|
||||
- name: Free Disk Space
|
||||
if: matrix.os == 'ubuntu-latest' || matrix.os == 'ubuntu-24.04-arm'
|
||||
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: macOS Select Xcode 26.2
|
||||
if: matrix.os == 'macos-15-intel' || matrix.os == 'macos-26'
|
||||
run: |
|
||||
sudo xcode-select -s /Applications/Xcode_26.2.app
|
||||
xcodebuild -version
|
||||
|
||||
- name: macOS Show Toolchain
|
||||
if: matrix.os == 'macos-15-intel' || matrix.os == 'macos-26'
|
||||
run: |
|
||||
xcodebuild -version
|
||||
actool --version
|
||||
|
||||
# NOTICE:
|
||||
# pnpm 11 does not ship a working standalone executable for Intel macOS.
|
||||
# Install pnpm through npm so it uses the Node.js runtime from setup-node.
|
||||
# https://github.com/pnpm/pnpm/issues/11423
|
||||
# Remove this branch when the project uses pnpm 12 or later.
|
||||
- uses: actions/setup-node@v6
|
||||
if: matrix.os == 'macos-15-intel'
|
||||
with:
|
||||
node-version: 26.7.0
|
||||
|
||||
- name: Install pnpm with npm
|
||||
if: matrix.os == 'macos-15-intel'
|
||||
run: npm install --global pnpm@11.24.0
|
||||
|
||||
- name: Get pnpm store path
|
||||
if: matrix.os == 'macos-15-intel'
|
||||
id: pnpm-store
|
||||
run: echo "path=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Cache pnpm store
|
||||
if: matrix.os == 'macos-15-intel'
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ${{ steps.pnpm-store.outputs.path }}
|
||||
key: ${{ runner.os }}-${{ runner.arch }}-pnpm-store-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-${{ runner.arch }}-pnpm-store-
|
||||
|
||||
- uses: pnpm/setup@v2
|
||||
if: matrix.os != 'macos-15-intel'
|
||||
with:
|
||||
runtime: node@26.7.0
|
||||
cache: true
|
||||
install: false
|
||||
|
||||
- name: Install macOS System Dependencies for node-canvas
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
brew install pkg-config cairo pango jpeg giflib librsvg
|
||||
|
||||
- run: pnpm install --frozen-lockfile
|
||||
|
||||
# ---------
|
||||
# Build
|
||||
# ---------
|
||||
|
||||
- run: pnpm run build:packages
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: '10.0.x'
|
||||
|
||||
- name: Setup Godot
|
||||
uses: chickensoft-games/setup-godot@v2
|
||||
with:
|
||||
version: '4.7.1'
|
||||
use-dotnet: true
|
||||
include-templates: true
|
||||
|
||||
- name: Export Godot Stage (Windows)
|
||||
if: matrix.os == 'windows-latest'
|
||||
working-directory: ./engines/stage-tamagotchi-godot
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p out/win
|
||||
godot --headless --export-release "Windows Desktop" out/win/godot-stage.exe
|
||||
|
||||
- name: Export Godot Stage (macOS)
|
||||
if: matrix.os == 'macos-15-intel' || matrix.os == 'macos-26'
|
||||
working-directory: ./engines/stage-tamagotchi-godot
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p out/mac
|
||||
godot --headless --export-release "macOS" out/mac/godot-stage.app
|
||||
|
||||
- name: Export Godot Stage (Linux)
|
||||
if: matrix.os == 'ubuntu-latest' || matrix.os == 'ubuntu-24.04-arm'
|
||||
working-directory: ./engines/stage-tamagotchi-godot
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p out/linux
|
||||
godot --headless --export-release "Linux ${{ matrix.arch }}" out/linux/godot-stage
|
||||
|
||||
- name: Build (Windows Only) # Windows
|
||||
if: matrix.os == 'windows-latest'
|
||||
run: pnpm run -F @proj-airi/stage-tamagotchi build && pnpm -F @proj-airi/stage-tamagotchi exec electron-builder build ${{ matrix.builder-args }} --publish=${{ (inputs.build_only || inputs.artifacts_only) && 'never' || 'onTagOrDraft' }}
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build (macOS Only) # macOS
|
||||
if: matrix.os == 'macos-15-intel' || matrix.os == 'macos-26'
|
||||
run: |
|
||||
echo "$CSC_CONTENT" | base64 --decode > apps/stage-tamagotchi/apple-developer-code-signing.p12
|
||||
export CSC_LINK="./apple-developer-code-signing.p12"
|
||||
pnpm run -F @proj-airi/stage-tamagotchi build && pnpm -F @proj-airi/stage-tamagotchi exec electron-builder build ${{ matrix.builder-args }} --publish=${{ (inputs.build_only || inputs.artifacts_only) && 'never' || 'onTagOrDraft' }}
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CSC_CONTENT: ${{ secrets.CSC_CONTENT }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
|
||||
APPLE_ID: ${{ secrets.APPLE_DEVELOPER_APPLE_ID }}
|
||||
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_DEVELOPER_APPLE_APP_SPECIFIC_PASSWORD }}
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_DEVELOPER_TEAM_ID }}
|
||||
|
||||
- name: Build (Linux Only) # Linux
|
||||
if: matrix.os == 'ubuntu-latest' || matrix.os == 'ubuntu-24.04-arm'
|
||||
run: pnpm run -F @proj-airi/stage-tamagotchi build && pnpm -F @proj-airi/stage-tamagotchi exec electron-builder build ${{ matrix.builder-args }} --publish=${{ (inputs.build_only || inputs.artifacts_only) && 'never' || 'onTagOrDraft' }}
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Setup Flatpak (Linux Only)
|
||||
if: ${{ matrix.os == 'ubuntu-latest' || matrix.os == 'ubuntu-24.04-arm' }}
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install -y flatpak flatpak-builder elfutils
|
||||
flatpak --version
|
||||
flatpak --user remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
|
||||
|
||||
- name: Build Flatpak (Linux Only) # Flatpak
|
||||
if: ${{ matrix.os == 'ubuntu-latest' || matrix.os == 'ubuntu-24.04-arm' }}
|
||||
working-directory: ./apps/stage-tamagotchi
|
||||
run: |
|
||||
mkdir -p dist
|
||||
# Auto-install required SDK/Platform/BaseApp from Flathub in user scope
|
||||
flatpak-builder --user --install-deps-from=flathub ./flatpak ai.moeru.airi.flatpak.yml --force-clean
|
||||
flatpak build-export ./flatpak-repo ./flatpak
|
||||
export FLATPAK_OUTPUT_NAME=$(pnpm exec tsx scripts/artifacts-metadata.ts ${{ matrix.target }} --get-output-filename flatpak)
|
||||
flatpak build-bundle ./flatpak-repo dist/${FLATPAK_OUTPUT_NAME} ai.moeru.airi
|
||||
|
||||
# ---------
|
||||
# Nightly (schedule) builds only
|
||||
# ---------
|
||||
|
||||
- name: Get Artifacts Envs (Nightly + Windows Only)
|
||||
if: ${{ github.event_name == 'schedule' && matrix.os == 'windows-latest' }}
|
||||
working-directory: ./apps/stage-tamagotchi
|
||||
run: |
|
||||
echo "BUNDLE_NAME=$(pnpm exec tsx scripts/artifacts-metadata.ts ${{ matrix.target }} --get-bundle-name)" >> $env:GITHUB_ENV
|
||||
echo "VERSION=$(pnpm exec tsx scripts/artifacts-metadata.ts ${{ matrix.target }} --get-version)" >> $env:GITHUB_ENV
|
||||
|
||||
- name: Get Artifacts Envs (Nightly + Non-Windows)
|
||||
if: ${{ github.event_name == 'schedule' && matrix.os != 'windows-latest' }}
|
||||
working-directory: ./apps/stage-tamagotchi
|
||||
run: |
|
||||
echo "VERSION=$(pnpm exec tsx scripts/artifacts-metadata.ts ${{ matrix.target }} --get-version)" >> $GITHUB_ENV
|
||||
|
||||
- name: Get Artifacts Envs (Nightly + macOS Only)
|
||||
if: ${{ github.event_name == 'schedule' && (matrix.os == 'macos-26' || matrix.os == 'macos-15-intel') }}
|
||||
working-directory: ./apps/stage-tamagotchi
|
||||
run: |
|
||||
echo "BUNDLE_NAME=$(pnpm exec tsx scripts/artifacts-metadata.ts ${{ matrix.target }} --get-bundle-name)" >> $GITHUB_ENV
|
||||
|
||||
- name: Rename Artifacts (Nightly)
|
||||
if: ${{ github.event_name == 'schedule' }}
|
||||
run:
|
||||
pnpm run -F @proj-airi/stage-tamagotchi rename-artifacts ${{ matrix.target }}
|
||||
|
||||
- name: Get Linux Artifact Names (Nightly + Linux Only)
|
||||
if: ${{ github.event_name == 'schedule' && (matrix.os == 'ubuntu-latest' || matrix.os == 'ubuntu-24.04-arm') }}
|
||||
working-directory: ./apps/stage-tamagotchi
|
||||
run: |
|
||||
echo "DEB_BUNDLE_NAME=$(pnpm exec tsx scripts/artifacts-metadata.ts ${{ matrix.target }} --get-filename deb)" >> $GITHUB_ENV
|
||||
echo "RPM_BUNDLE_NAME=$(pnpm exec tsx scripts/artifacts-metadata.ts ${{ matrix.target }} --get-filename rpm)" >> $GITHUB_ENV
|
||||
echo "FLATPAK_BUNDLE_NAME=$(pnpm exec tsx scripts/artifacts-metadata.ts ${{ matrix.target }} --get-filename flatpak)" >> $GITHUB_ENV
|
||||
|
||||
- name: Upload Artifacts (Nightly + Non-Linux)
|
||||
if: ${{ github.event_name == 'schedule' && (matrix.os != 'ubuntu-latest' && matrix.os != 'ubuntu-24.04-arm') }}
|
||||
id: unsigned-artifacts-nightly
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ env.BUNDLE_NAME }}
|
||||
path: apps/stage-tamagotchi/bundle/${{ env.BUNDLE_NAME }}
|
||||
|
||||
- name: Upload Artifacts (Nightly + Linux deb)
|
||||
if: ${{ github.event_name == 'schedule' && (matrix.os == 'ubuntu-latest' || matrix.os == 'ubuntu-24.04-arm') }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ env.DEB_BUNDLE_NAME }}
|
||||
path: apps/stage-tamagotchi/bundle/${{ env.DEB_BUNDLE_NAME }}
|
||||
|
||||
- name: Upload Artifacts (Nightly + Linux rpm)
|
||||
if: ${{ github.event_name == 'schedule' && (matrix.os == 'ubuntu-latest' || matrix.os == 'ubuntu-24.04-arm') }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ env.RPM_BUNDLE_NAME }}
|
||||
path: apps/stage-tamagotchi/bundle/${{ env.RPM_BUNDLE_NAME }}
|
||||
|
||||
- name: Upload Flatpak Artifact (Nightly + Linux Only)
|
||||
if: ${{ github.event_name == 'schedule' && (matrix.os == 'ubuntu-latest' || matrix.os == 'ubuntu-24.04-arm') }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ env.FLATPAK_BUNDLE_NAME }}
|
||||
path: apps/stage-tamagotchi/bundle/${{ env.FLATPAK_BUNDLE_NAME }}
|
||||
|
||||
- name: Sign Windows Artifacts with SignPath (Nightly + Windows Only)
|
||||
id: signpath-nightly-windows
|
||||
continue-on-error: true
|
||||
uses: signpath/github-action-submit-signing-request@v2
|
||||
if: ${{ github.event_name == 'schedule' && (matrix.os == 'windows-latest' && github.repository == 'moeru-ai/airi') }}
|
||||
with:
|
||||
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
|
||||
organization-id: '${{ secrets.SIGNPATH_ORGANIZATION_ID }}'
|
||||
project-slug: 'airi'
|
||||
signing-policy-slug: 'test-signing'
|
||||
artifact-configuration-slug: ci-github-actions-artifacts-windows
|
||||
github-artifact-id: '${{ steps.unsigned-artifacts-nightly.outputs.artifact-id }}'
|
||||
wait-for-completion: true
|
||||
wait-for-completion-timeout-in-seconds: 900 # 15 minutes
|
||||
download-signed-artifact-timeout-in-seconds: 900 # 15 minutes
|
||||
output-artifact-directory: apps/stage-tamagotchi/bundle/signed/windows/
|
||||
|
||||
- name: Warn When Windows Signing Fails (Nightly)
|
||||
if: ${{ github.event_name == 'schedule' && matrix.os == 'windows-latest' && steps.signpath-nightly-windows.outcome != 'success' }}
|
||||
run: |
|
||||
echo "::warning::SignPath Windows signing failed for nightly build. Continuing with unsigned artifact at apps/stage-tamagotchi/bundle/${{ env.BUNDLE_NAME }}."
|
||||
|
||||
- name: Upload Signed Artifacts (Nightly + Non-Linux)
|
||||
if: ${{ github.event_name == 'schedule' && matrix.os == 'windows-latest' && steps.signpath-nightly-windows.outcome == 'success' }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ env.BUNDLE_NAME }}
|
||||
path: apps/stage-tamagotchi/bundle/signed/windows/${{ env.BUNDLE_NAME }}
|
||||
overwrite: true
|
||||
|
||||
- name: Upload Unsigned Windows Artifacts Fallback (Nightly)
|
||||
if: ${{ github.event_name == 'schedule' && matrix.os == 'windows-latest' && steps.signpath-nightly-windows.outcome != 'success' }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ env.BUNDLE_NAME }}
|
||||
path: apps/stage-tamagotchi/bundle/${{ env.BUNDLE_NAME }}
|
||||
overwrite: true
|
||||
|
||||
# NOTICE: Electron Builder generates latest-x64.yml during the build step, before this workflow
|
||||
# submits the Windows installer to SignPath. SignPath re-signs the .exe and changes its bytes,
|
||||
# which changes the updater hashes too. Regenerating latest-x64.yml from the signed installer keeps
|
||||
# the published Windows update metadata aligned with the final released artifact.
|
||||
- name: Regenerate Windows latest-x64.yml (Nightly + Windows Only)
|
||||
if: ${{ github.event_name == 'schedule' && matrix.os == 'windows-latest' && steps.signpath-nightly-windows.outcome == 'success' }}
|
||||
run: |
|
||||
pnpm -F @proj-airi/stage-tamagotchi run regenerate-windows-latest --input apps/stage-tamagotchi/bundle/signed/windows/${{ env.BUNDLE_NAME }} --output apps/stage-tamagotchi/bundle/latest-x64.yml --version ${{ env.VERSION }}
|
||||
|
||||
- name: Regenerate Windows latest-x64.yml From Unsigned Artifact (Nightly Fallback)
|
||||
if: ${{ github.event_name == 'schedule' && matrix.os == 'windows-latest' && steps.signpath-nightly-windows.outcome != 'success' }}
|
||||
run: |
|
||||
pnpm -F @proj-airi/stage-tamagotchi run regenerate-windows-latest --input apps/stage-tamagotchi/bundle/${{ env.BUNDLE_NAME }} --output apps/stage-tamagotchi/bundle/latest-x64.yml --version ${{ env.VERSION }}
|
||||
|
||||
# ---------
|
||||
# Workflow Dispatch only
|
||||
# ---------
|
||||
|
||||
- name: Get Artifacts Envs (Manual + Windows Only)
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && matrix.os == 'windows-latest' }}
|
||||
working-directory: ./apps/stage-tamagotchi
|
||||
run: |
|
||||
echo "BUNDLE_NAME=$(pnpm exec tsx scripts/artifacts-metadata.ts ${{ matrix.target }} --get-bundle-name --release ${{ !inputs.build_only && !inputs.artifacts_only }} --tag ${{ inputs.tag }} --auto-tag ${{ !inputs.build_only }})" >> $env:GITHUB_ENV
|
||||
echo "VERSION=$(pnpm exec tsx scripts/artifacts-metadata.ts ${{ matrix.target }} --get-version --release ${{ !inputs.build_only && !inputs.artifacts_only }} --tag ${{ inputs.tag }} --auto-tag ${{ !inputs.build_only }})" >> $env:GITHUB_ENV
|
||||
|
||||
- name: Get Artifacts Envs (Manual + Non-Windows)
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && matrix.os != 'windows-latest' }}
|
||||
working-directory: ./apps/stage-tamagotchi
|
||||
run: |
|
||||
echo "VERSION=$(pnpm exec tsx scripts/artifacts-metadata.ts ${{ matrix.target }} --get-version --release ${{ !inputs.build_only && !inputs.artifacts_only }} --tag ${{ inputs.tag }} --auto-tag ${{ !inputs.build_only }})" >> $GITHUB_ENV
|
||||
|
||||
- name: Get Artifacts Envs (Manual + macOS Only)
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && (matrix.os == 'macos-26' || matrix.os == 'macos-15-intel') }}
|
||||
working-directory: ./apps/stage-tamagotchi
|
||||
run: |
|
||||
echo "BUNDLE_NAME=$(pnpm exec tsx scripts/artifacts-metadata.ts ${{ matrix.target }} --get-bundle-name --release ${{ !inputs.build_only && !inputs.artifacts_only }} --tag ${{ inputs.tag }} --auto-tag ${{ !inputs.build_only }})" >> $GITHUB_ENV
|
||||
|
||||
- name: Rename Artifacts (Manual)
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
run: |
|
||||
pnpm run -F @proj-airi/stage-tamagotchi rename-artifacts ${{ matrix.target }} --release ${{ !inputs.build_only && !inputs.artifacts_only }} --tag ${{ inputs.tag }} --auto-tag ${{ !inputs.build_only }}
|
||||
|
||||
- name: Get Linux Artifact Names (Manual + Non-Release + Linux Only)
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && !inputs.build_only && inputs.artifacts_only && (matrix.os == 'ubuntu-latest' || matrix.os == 'ubuntu-24.04-arm') }}
|
||||
working-directory: ./apps/stage-tamagotchi
|
||||
run: |
|
||||
echo "DEB_BUNDLE_NAME=$(pnpm exec tsx scripts/artifacts-metadata.ts ${{ matrix.target }} --get-filename deb --release ${{ !inputs.build_only && !inputs.artifacts_only }} --tag ${{ inputs.tag }} --auto-tag ${{ !inputs.build_only }})" >> $GITHUB_ENV
|
||||
echo "RPM_BUNDLE_NAME=$(pnpm exec tsx scripts/artifacts-metadata.ts ${{ matrix.target }} --get-filename rpm --release ${{ !inputs.build_only && !inputs.artifacts_only }} --tag ${{ inputs.tag }} --auto-tag ${{ !inputs.build_only }})" >> $GITHUB_ENV
|
||||
echo "FLATPAK_BUNDLE_NAME=$(pnpm exec tsx scripts/artifacts-metadata.ts ${{ matrix.target }} --get-filename flatpak --release ${{ !inputs.build_only && !inputs.artifacts_only }} --tag ${{ inputs.tag }} --auto-tag ${{ !inputs.build_only }})" >> $GITHUB_ENV
|
||||
|
||||
- name: Upload Artifacts (Manual + Non-Release + Non-Linux)
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && !inputs.build_only && inputs.artifacts_only && (matrix.os != 'ubuntu-latest' && matrix.os != 'ubuntu-24.04-arm') }}
|
||||
id: unsigned-artifacts-workflow-dispatch
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ env.BUNDLE_NAME }}
|
||||
path: apps/stage-tamagotchi/bundle/${{ env.BUNDLE_NAME }}
|
||||
|
||||
- name: Upload Artifacts (Manual + Non-Release + Linux deb)
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && !inputs.build_only && inputs.artifacts_only && (matrix.os == 'ubuntu-latest' || matrix.os == 'ubuntu-24.04-arm') }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ env.DEB_BUNDLE_NAME }}
|
||||
path: apps/stage-tamagotchi/bundle/${{ env.DEB_BUNDLE_NAME }}
|
||||
|
||||
- name: Upload Artifacts (Manual + Non-Release + Linux rpm)
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && !inputs.build_only && inputs.artifacts_only && (matrix.os == 'ubuntu-latest' || matrix.os == 'ubuntu-24.04-arm') }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ env.RPM_BUNDLE_NAME }}
|
||||
path: apps/stage-tamagotchi/bundle/${{ env.RPM_BUNDLE_NAME }}
|
||||
|
||||
- name: Upload Flatpak Artifact (Manual + Non-Release + Linux)
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && !inputs.build_only && inputs.artifacts_only && (matrix.os == 'ubuntu-latest' || matrix.os == 'ubuntu-24.04-arm') }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ env.FLATPAK_BUNDLE_NAME }}
|
||||
path: apps/stage-tamagotchi/bundle/${{ env.FLATPAK_BUNDLE_NAME }}
|
||||
|
||||
- name: Sign Windows Artifacts with SignPath (Manual + Windows Only)
|
||||
id: signpath-manual-windows
|
||||
continue-on-error: true
|
||||
uses: signpath/github-action-submit-signing-request@v2
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && !inputs.build_only && inputs.artifacts_only && (matrix.os == 'windows-latest' && github.repository == 'moeru-ai/airi') }}
|
||||
with:
|
||||
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
|
||||
organization-id: '${{ secrets.SIGNPATH_ORGANIZATION_ID }}'
|
||||
project-slug: 'airi'
|
||||
signing-policy-slug: 'test-signing'
|
||||
artifact-configuration-slug: ci-github-actions-artifacts-windows
|
||||
github-artifact-id: '${{ steps.unsigned-artifacts-workflow-dispatch.outputs.artifact-id }}'
|
||||
wait-for-completion: true
|
||||
wait-for-completion-timeout-in-seconds: 900 # 15 minutes
|
||||
download-signed-artifact-timeout-in-seconds: 900 # 15 minutes
|
||||
output-artifact-directory: apps/stage-tamagotchi/bundle/signed/windows/
|
||||
|
||||
- name: Warn When Windows Signing Fails (Manual)
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && !inputs.build_only && inputs.artifacts_only && matrix.os == 'windows-latest' && steps.signpath-manual-windows.outcome != 'success' }}
|
||||
run: |
|
||||
echo "::warning::SignPath Windows signing failed for workflow_dispatch artifact build. Continuing with unsigned artifact at apps/stage-tamagotchi/bundle/${{ env.BUNDLE_NAME }}."
|
||||
|
||||
- name: Move Signed Artifacts (Manual + Release + Windows Only)
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && !inputs.build_only && inputs.artifacts_only && matrix.os == 'windows-latest' && steps.signpath-manual-windows.outcome == 'success' }}
|
||||
run: |
|
||||
Move-Item -Force apps/stage-tamagotchi/bundle/signed/windows/${{ env.BUNDLE_NAME }} apps/stage-tamagotchi/bundle/${{ env.BUNDLE_NAME }}
|
||||
|
||||
- name: Upload Signed Artifacts (Manual + Windows Only)
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && !inputs.build_only && inputs.artifacts_only && (matrix.os == 'windows-latest') }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ env.BUNDLE_NAME }}
|
||||
path: apps/stage-tamagotchi/bundle/${{ env.BUNDLE_NAME }}
|
||||
overwrite: true
|
||||
|
||||
# NOTICE: Electron Builder already wrote latest-x64.yml before SignPath signed the installer.
|
||||
# After the signed .exe replaces the unsigned one, we must rebuild latest-x64.yml so its hashes
|
||||
# describe the final Windows artifact that users will actually download.
|
||||
- name: Regenerate Windows latest-x64.yml (Manual + Windows Only)
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && !inputs.build_only && inputs.artifacts_only && matrix.os == 'windows-latest' }}
|
||||
run: |
|
||||
pnpm -F @proj-airi/stage-tamagotchi run regenerate-windows-latest --input apps/stage-tamagotchi/bundle/${{ env.BUNDLE_NAME }} --output apps/stage-tamagotchi/bundle/latest-x64.yml --version ${{ env.VERSION }}
|
||||
|
||||
- name: Upload To GitHub Releases (Manual + Release + Overwrite Release)
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && !inputs.build_only && !inputs.artifacts_only }}
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: |
|
||||
apps/stage-tamagotchi/bundle/${{ env.PRODUCT_NAME }}-*.exe
|
||||
apps/stage-tamagotchi/bundle/${{ env.PRODUCT_NAME }}-*.zip
|
||||
apps/stage-tamagotchi/bundle/${{ env.PRODUCT_NAME }}-*.dmg
|
||||
apps/stage-tamagotchi/bundle/${{ env.PRODUCT_NAME }}-*.deb
|
||||
apps/stage-tamagotchi/bundle/${{ env.PRODUCT_NAME }}-*.rpm
|
||||
apps/stage-tamagotchi/bundle/${{ env.PRODUCT_NAME }}-*.flatpak
|
||||
apps/stage-tamagotchi/bundle/latest-*.yml
|
||||
append_body: true
|
||||
tag_name: ${{ inputs.tag }}
|
||||
|
||||
# ---------
|
||||
# Version push
|
||||
# ---------
|
||||
|
||||
- name: Rename Artifacts (Automatic)
|
||||
if: ${{ github.event_name == 'release' }}
|
||||
run: |
|
||||
pnpm run -F @proj-airi/stage-tamagotchi rename-artifacts ${{ matrix.target }} --release --auto-tag
|
||||
|
||||
- name: Get Artifacts Envs (Automatic + Windows Only)
|
||||
if: ${{ github.event_name == 'release' && matrix.os == 'windows-latest' }}
|
||||
working-directory: ./apps/stage-tamagotchi
|
||||
run: |
|
||||
echo "BUNDLE_NAME=$(pnpm exec tsx scripts/artifacts-metadata.ts ${{ matrix.target }} --get-bundle-name --release ${{ !inputs.build_only && !inputs.artifacts_only }} --tag ${{ inputs.tag }} --auto-tag ${{ !inputs.build_only }})" >> $env:GITHUB_ENV
|
||||
echo "VERSION=$(pnpm exec tsx scripts/artifacts-metadata.ts ${{ matrix.target }} --get-version --release ${{ !inputs.build_only && !inputs.artifacts_only }} --tag ${{ inputs.tag }} --auto-tag ${{ !inputs.build_only }})" >> $env:GITHUB_ENV
|
||||
|
||||
- name: Get Artifacts Envs (Automatic + Non-Windows)
|
||||
if: ${{ github.event_name == 'release' && matrix.os != 'windows-latest' }}
|
||||
working-directory: ./apps/stage-tamagotchi
|
||||
run: |
|
||||
echo "BUNDLE_NAME=$(pnpm exec tsx scripts/artifacts-metadata.ts ${{ matrix.target }} --get-bundle-name --release --auto-tag)" >> $GITHUB_ENV
|
||||
|
||||
- name: Upload Artifacts (Automatic + Windows Only)
|
||||
if: ${{ github.event_name == 'release' && matrix.os == 'windows-latest' }}
|
||||
id: unsigned-artifacts-release
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ env.BUNDLE_NAME }}
|
||||
path: apps/stage-tamagotchi/bundle/${{ env.BUNDLE_NAME }}
|
||||
|
||||
- name: Sign Windows Artifacts with SignPath (Nightly + Windows Only)
|
||||
id: signpath-release-windows
|
||||
continue-on-error: true
|
||||
uses: signpath/github-action-submit-signing-request@v2
|
||||
if: ${{ github.event_name == 'release' && (matrix.os == 'windows-latest' && github.repository == 'moeru-ai/airi') }}
|
||||
with:
|
||||
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
|
||||
organization-id: '${{ secrets.SIGNPATH_ORGANIZATION_ID }}'
|
||||
project-slug: 'airi'
|
||||
signing-policy-slug: 'test-signing'
|
||||
artifact-configuration-slug: ci-github-actions-artifacts-windows
|
||||
github-artifact-id: '${{ steps.unsigned-artifacts-release.outputs.artifact-id }}'
|
||||
wait-for-completion: true
|
||||
wait-for-completion-timeout-in-seconds: 900 # 15 minutes
|
||||
download-signed-artifact-timeout-in-seconds: 900 # 15 minutes
|
||||
output-artifact-directory: apps/stage-tamagotchi/bundle/signed/windows/
|
||||
|
||||
- name: Warn When Windows Signing Fails (Release)
|
||||
if: ${{ github.event_name == 'release' && matrix.os == 'windows-latest' && steps.signpath-release-windows.outcome != 'success' }}
|
||||
run: |
|
||||
echo "::warning::SignPath Windows signing failed for release build. Continuing with unsigned artifact at apps/stage-tamagotchi/bundle/${{ env.BUNDLE_NAME }}."
|
||||
|
||||
- name: Move Signed Artifacts (Automatic + Windows Only)
|
||||
if: ${{ github.event_name == 'release' && matrix.os == 'windows-latest' && steps.signpath-release-windows.outcome == 'success' }}
|
||||
run: |
|
||||
Move-Item -Force apps/stage-tamagotchi/bundle/signed/windows/${{ env.BUNDLE_NAME }} apps/stage-tamagotchi/bundle/${{ env.BUNDLE_NAME }}
|
||||
|
||||
# NOTICE: The root cause here is the build/signing order: latest-x64.yml is produced by Electron
|
||||
# Builder before SignPath re-signs the installer. That post-build signing step mutates the .exe,
|
||||
# so the updater metadata becomes stale. Recomputing latest-x64.yml after the signed file is moved
|
||||
# into its final bundle path makes the release upload self-consistent again.
|
||||
- name: Regenerate Windows latest manifest (Automatic + Windows Only)
|
||||
if: ${{ github.event_name == 'release' && matrix.os == 'windows-latest' }}
|
||||
run: |
|
||||
pnpm -F @proj-airi/stage-tamagotchi run regenerate-windows-latest --input apps/stage-tamagotchi/bundle/${{ env.BUNDLE_NAME }} --output apps/stage-tamagotchi/bundle/latest-x64.yml --version ${{ env.VERSION }}
|
||||
|
||||
- name: Upload Distribution Artifact (Automatic + macOS arm64 Only)
|
||||
if: ${{ github.event_name == 'release' && matrix.os == 'macos-26' }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: distribution-osx
|
||||
path: apps/stage-tamagotchi/bundle/${{ env.BUNDLE_NAME }}
|
||||
|
||||
- name: Upload Distribution Artifact (Automatic + Windows Only)
|
||||
if: ${{ github.event_name == 'release' && matrix.os == 'windows-latest' }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: distribution-win
|
||||
path: apps/stage-tamagotchi/bundle/${{ env.BUNDLE_NAME }}
|
||||
|
||||
- name: Upload Distribution Artifact (Automatic + Linux x64 Only)
|
||||
if: ${{ github.event_name == 'release' && matrix.os == 'ubuntu-latest' }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: distribution-linux-x64
|
||||
path: apps/stage-tamagotchi/bundle/${{ env.BUNDLE_NAME }}
|
||||
|
||||
- name: Upload Distribution Artifact (Automatic + Linux arm64 Only)
|
||||
if: ${{ github.event_name == 'release' && matrix.os == 'ubuntu-24.04-arm' }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: distribution-linux-arm64
|
||||
path: apps/stage-tamagotchi/bundle/${{ env.BUNDLE_NAME }}
|
||||
|
||||
- name: Upload To GitHub Releases (Automatic)
|
||||
if: ${{ github.event_name == 'release' }}
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
# Possible auto updater files:
|
||||
# Windows: latest-x64.yml
|
||||
# macOS: latest-arm64-mac.yml, latest-x64-mac.yml
|
||||
# Linux: latest-arm64-linux.yml (arm64), latest-x64-linux.yml (x64)
|
||||
files: |
|
||||
apps/stage-tamagotchi/bundle/${{ env.PRODUCT_NAME }}-*.exe
|
||||
apps/stage-tamagotchi/bundle/${{ env.PRODUCT_NAME }}-*.zip
|
||||
apps/stage-tamagotchi/bundle/${{ env.PRODUCT_NAME }}-*.dmg
|
||||
apps/stage-tamagotchi/bundle/${{ env.PRODUCT_NAME }}-*.deb
|
||||
apps/stage-tamagotchi/bundle/${{ env.PRODUCT_NAME }}-*.rpm
|
||||
apps/stage-tamagotchi/bundle/${{ env.PRODUCT_NAME }}-*.flatpak
|
||||
apps/stage-tamagotchi/bundle/latest-*.yml
|
||||
append_body: true
|
||||
|
||||
publish-gitcode-release:
|
||||
name: Publish GitCode Release Mirror
|
||||
needs: build
|
||||
if: ${{ always() && github.repository == 'moeru-ai/airi' && (github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && !inputs.build_only && !inputs.artifacts_only && inputs.tag != '')) }}
|
||||
continue-on-error: true
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Validate release mirror tools
|
||||
run: |
|
||||
gh --version
|
||||
jq --version
|
||||
curl --version
|
||||
|
||||
- name: Publish release assets to GitCode
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITCODE_TOKEN: ${{ secrets.GITCODE_TOKEN }}
|
||||
GITCODE_OWNER: ${{ secrets.GITCODE_OWNER }}
|
||||
GITCODE_REPO: ${{ secrets.GITCODE_REPO }}
|
||||
GITCODE_RELEASE_TAG: ${{ github.event.release.tag_name || inputs.tag }}
|
||||
run: bash .github/scripts/publish-gitcode-release.sh
|
||||
|
||||
publish-distribution:
|
||||
name: Publish Distribution
|
||||
needs: build
|
||||
if: ${{ github.event_name == 'release' }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- artifact_name: distribution-osx
|
||||
platform: osx
|
||||
- artifact_name: distribution-win
|
||||
platform: win
|
||||
- artifact_name: distribution-linux-x64
|
||||
platform: linux
|
||||
- artifact_name: distribution-linux-arm64
|
||||
platform: linux
|
||||
steps:
|
||||
- name: Resolve release version
|
||||
run: |
|
||||
echo "VERSION=${GITHUB_REF_NAME#v}" >> $GITHUB_ENV
|
||||
|
||||
- name: Download distribution artifact
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
name: ${{ matrix.artifact_name }}
|
||||
path: dist/${{ matrix.artifact_name }}
|
||||
|
||||
- name: Resolve artifact path
|
||||
run: |
|
||||
echo "ARTIFACT_PATH=$(find dist/${{ matrix.artifact_name }} -maxdepth 1 -mindepth 1 | head -n 1)" >> $GITHUB_ENV
|
||||
|
||||
- name: Setup butler
|
||||
uses: remarkablegames/setup-butler@v2
|
||||
|
||||
# https://itch.io/docs/butler/pushing.html
|
||||
- name: Publish distribution artifact to itch.io
|
||||
run: butler push "${{ env.ARTIFACT_PATH }}" nekomeowww/airi:${{ matrix.platform }} --userversion "${{ env.VERSION }}"
|
||||
env:
|
||||
BUTLER_API_KEY: ${{ secrets.GAME_PUBLISHING_ITCHIO }}
|
||||
@@ -16,11 +16,13 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: pnpm/setup@v2
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
runtime: node@26.7.0
|
||||
cache: true
|
||||
install: false
|
||||
node-version: 26.7.0
|
||||
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version: 1.4.2
|
||||
|
||||
- name: Configure npm registry
|
||||
uses: actions/setup-node@v6
|
||||
@@ -29,11 +31,11 @@ jobs:
|
||||
# https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- run: pnpm run build:packages
|
||||
- run: pnpm run -F @proj-airi/airi-plugin-vscode build
|
||||
- run: pnpm run -F vscode-airi build
|
||||
- run: pnpm run publish
|
||||
- run: bun install --frozen-lockfile
|
||||
- run: bun run build:packages
|
||||
- run: bun run --filter @proj-airi/airi-plugin-vscode build
|
||||
- run: bun run --filter vscode-airi build
|
||||
- run: bun run publish
|
||||
working-directory: ./integrations/vscode/vscode-airi
|
||||
env:
|
||||
VSCE_TOKEN: ${{ secrets.VSCE_TOKEN }}
|
||||
|
||||
@@ -21,18 +21,20 @@ jobs:
|
||||
with:
|
||||
ref: main
|
||||
|
||||
- uses: pnpm/setup@v2
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
runtime: node@26.7.0
|
||||
cache: true
|
||||
install: false
|
||||
- run: pnpm install --frozen-lockfile
|
||||
node-version: 26.7.0
|
||||
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version: 1.4.2
|
||||
- run: bun install --frozen-lockfile
|
||||
|
||||
- name: Pull with rebase
|
||||
run: git pull origin main --rebase --autostash
|
||||
|
||||
- name: Generate sponsors svg
|
||||
run: pnpm run sponsors:generate
|
||||
run: bun run sponsors:generate
|
||||
|
||||
- name: Remove private SponsorKit cache
|
||||
run: rm -f docs/content/public/assets/sponsors/.cache.json
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
name: Update Nix assets Hash
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'apps/stage-web/package.json'
|
||||
- 'apps/stage-web/vite.config.ts'
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
update:
|
||||
if: github.event_name == 'workflow_dispatch' || !github.event.repository.fork
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Why?
|
||||
#
|
||||
# failed to
|
||||
# $ nix build .#airi-pnpm-deps
|
||||
# > airi-pnpm-deps> Running phase: fixupPhase
|
||||
# > error: writing to file: No space left on device
|
||||
- name: Free Disk Space
|
||||
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: main # Use main regardless of workflow_dispatch branch
|
||||
# Authenticate git with PAT so that pushing to head retriggers CI
|
||||
token: ${{ secrets.HASH_UPDATE_TOKEN }}
|
||||
|
||||
- uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
extra_nix_config: experimental-features = nix-command flakes
|
||||
|
||||
- name: Update Hash
|
||||
run: nix/update-assets-hash.sh
|
||||
|
||||
- name: Check for changes
|
||||
id: changes
|
||||
run: |
|
||||
if git diff --quiet; then
|
||||
echo "has_changes=false" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "has_changes=true" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Create PR
|
||||
if: steps.changes.outputs.has_changes == 'true'
|
||||
env:
|
||||
# Create PR with PAT to trigger CI
|
||||
GH_TOKEN: ${{ secrets.HASH_UPDATE_TOKEN }}
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git add nix/assets-hash.txt
|
||||
git commit -m 'chore(nix): update assets hash'
|
||||
git push -f origin HEAD:chore/update-nix-assets-hash
|
||||
|
||||
# Create PR if it doesn't already exist
|
||||
existing_pr=$(gh pr list --head chore/update-nix-assets-hash --json number -q '.[0].number' 2>/dev/null || true)
|
||||
if [ -z "$existing_pr" ]; then
|
||||
gh pr create \
|
||||
--base main \
|
||||
--head chore/update-nix-assets-hash \
|
||||
--title 'chore(nix): update assets hash' \
|
||||
--body 'Auto-generated by CI to keep Nix asset hash up-to-date.'
|
||||
fi
|
||||
|
||||
# Enable auto-merge so PR merges once checks pass
|
||||
gh pr merge --squash --auto --delete-branch chore/update-nix-assets-hash
|
||||
@@ -1,74 +0,0 @@
|
||||
name: Update Nix pnpmDeps Hash
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'pnpm-lock.yaml'
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
update:
|
||||
if: github.event_name == 'workflow_dispatch' || !github.event.repository.fork
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Why?
|
||||
#
|
||||
# failed to
|
||||
# $ nix build .#airi-pnpm-deps
|
||||
# > airi-pnpm-deps> Running phase: fixupPhase
|
||||
# > error: writing to file: No space left on device
|
||||
- name: Free Disk Space
|
||||
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: main # Use main regardless of workflow_dispatch branch
|
||||
# Authenticate git with PAT so that pushing to head retriggers CI
|
||||
token: ${{ secrets.HASH_UPDATE_TOKEN }}
|
||||
|
||||
- uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
extra_nix_config: experimental-features = nix-command flakes
|
||||
|
||||
- name: Update Hash
|
||||
run: nix/update-pnpm-deps-hash.sh
|
||||
|
||||
- name: Check for changes
|
||||
id: changes
|
||||
run: |
|
||||
if git diff --quiet; then
|
||||
echo "has_changes=false" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "has_changes=true" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Create PR
|
||||
if: steps.changes.outputs.has_changes == 'true'
|
||||
env:
|
||||
# Create PR with PAT to trigger CI
|
||||
GH_TOKEN: ${{ secrets.HASH_UPDATE_TOKEN }}
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git add nix/pnpm-deps-hash.txt
|
||||
git commit -m 'chore(nix): update pnpmDeps hash'
|
||||
git push -f origin HEAD:chore/update-nix-pnpm-deps-hash
|
||||
|
||||
# Create PR if it doesn't already exist
|
||||
existing_pr=$(gh pr list --head chore/update-nix-pnpm-deps-hash --json number -q '.[0].number' 2>/dev/null || true)
|
||||
if [ -z "$existing_pr" ]; then
|
||||
gh pr create \
|
||||
--base main \
|
||||
--head chore/update-nix-pnpm-deps-hash \
|
||||
--title 'chore(nix): update pnpmDeps hash' \
|
||||
--body 'Auto-generated by CI to keep Nix pnpmDeps hash up-to-date.'
|
||||
fi
|
||||
|
||||
# Enable auto-merge so PR merges once checks pass
|
||||
gh pr merge --squash --auto --delete-branch chore/update-nix-pnpm-deps-hash
|
||||
@@ -1,165 +0,0 @@
|
||||
name: Update (Post Release) README URLs
|
||||
|
||||
on:
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
- released
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: 'Release tag (e.g., v0.10.2)'
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: update-post-release-readme-urls
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
update:
|
||||
# Keep prereleases from replacing the stable README download buttons.
|
||||
if: github.event_name == 'workflow_dispatch' || !github.event.release.prerelease
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
README_BRANCH: automation/update-readme-release-links
|
||||
RELEASE_TAG: ${{ github.event.release.tag_name || inputs.tag }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: main
|
||||
persist-credentials: false
|
||||
|
||||
- uses: pnpm/setup@v2
|
||||
with:
|
||||
runtime: node@26.7.0
|
||||
cache: true
|
||||
install: false
|
||||
- run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Update README download links
|
||||
run: pnpm -F @proj-airi/stage-tamagotchi exec tsx scripts/update-readme-download-links.ts "$RELEASE_TAG"
|
||||
|
||||
- name: Pull with rebase
|
||||
run: git pull origin main --rebase --autostash
|
||||
|
||||
- name: Prepare README release update
|
||||
id: prepare
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.PAT_SLASH_COMMAND_DISPATCH }}
|
||||
run: |
|
||||
# The updater is only allowed to publish the generated README link changes.
|
||||
if ! git diff --quiet -- . ':(exclude)README.md' ':(exclude)docs/README*.md'; then
|
||||
echo "::error::Unexpected non-README changes were generated."
|
||||
git status --short
|
||||
exit 1
|
||||
fi
|
||||
|
||||
git add README.md 'docs/README*.md'
|
||||
if git diff --cached --quiet; then
|
||||
echo "No README release links changed."
|
||||
echo "changed=false" >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -z "$GH_TOKEN" ]; then
|
||||
echo "::error::PAT_SLASH_COMMAND_DISPATCH is required so the README update PR triggers required checks."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git"
|
||||
|
||||
REMOTE_BRANCH="$(git ls-remote --heads origin "refs/heads/${README_BRANCH}")"
|
||||
if [ -n "$REMOTE_BRANCH" ]; then
|
||||
git fetch origin "${README_BRANCH}:refs/remotes/origin/${README_BRANCH}"
|
||||
fi
|
||||
|
||||
git checkout -B "$README_BRANCH"
|
||||
PR_TITLE="chore: update README release artifacts to ${RELEASE_TAG}"
|
||||
git commit -m "$PR_TITLE"
|
||||
git push --force-with-lease origin "$README_BRANCH"
|
||||
|
||||
echo "changed=true" >> "$GITHUB_OUTPUT"
|
||||
echo "pr_title=$PR_TITLE" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Create or update README release PR
|
||||
if: steps.prepare.outputs.changed == 'true'
|
||||
uses: actions/github-script@v8
|
||||
env:
|
||||
PR_TITLE: ${{ steps.prepare.outputs.pr_title }}
|
||||
with:
|
||||
github-token: ${{ secrets.PAT_SLASH_COMMAND_DISPATCH }}
|
||||
script: |
|
||||
const { owner, repo } = context.repo;
|
||||
const head = `${owner}:${process.env.README_BRANCH}`;
|
||||
const body = [
|
||||
'## Description',
|
||||
'',
|
||||
`Updates stable desktop download links after the ${process.env.RELEASE_TAG} release.`,
|
||||
'',
|
||||
'## Linked Issues',
|
||||
'',
|
||||
'None.',
|
||||
'',
|
||||
'## Additional Context',
|
||||
'',
|
||||
'Generated by the post-release README workflow.',
|
||||
].join('\n');
|
||||
|
||||
const { data: openPullRequests } = await github.rest.pulls.list({
|
||||
owner,
|
||||
repo,
|
||||
state: 'open',
|
||||
base: 'main',
|
||||
head,
|
||||
per_page: 1,
|
||||
});
|
||||
|
||||
let pullRequest;
|
||||
if (openPullRequests.length > 0) {
|
||||
const { data } = await github.rest.pulls.update({
|
||||
owner,
|
||||
repo,
|
||||
pull_number: openPullRequests[0].number,
|
||||
title: process.env.PR_TITLE,
|
||||
body,
|
||||
});
|
||||
pullRequest = data;
|
||||
core.info(`Updated pull request #${pullRequest.number}.`);
|
||||
}
|
||||
else {
|
||||
const { data } = await github.rest.pulls.create({
|
||||
owner,
|
||||
repo,
|
||||
base: 'main',
|
||||
head: process.env.README_BRANCH,
|
||||
title: process.env.PR_TITLE,
|
||||
body,
|
||||
});
|
||||
pullRequest = data;
|
||||
core.info(`Created pull request #${pullRequest.number}.`);
|
||||
}
|
||||
|
||||
if (!pullRequest.auto_merge) {
|
||||
await github.graphql(
|
||||
`mutation EnableAutoMerge($pullRequestId: ID!) {
|
||||
enablePullRequestAutoMerge(input: {
|
||||
pullRequestId: $pullRequestId
|
||||
mergeMethod: SQUASH
|
||||
}) {
|
||||
pullRequest {
|
||||
number
|
||||
}
|
||||
}
|
||||
}`,
|
||||
{
|
||||
pullRequestId: pullRequest.node_id,
|
||||
},
|
||||
);
|
||||
core.info(`Enabled squash auto-merge for pull request #${pullRequest.number}.`);
|
||||
}
|
||||
@@ -19,18 +19,20 @@ jobs:
|
||||
fi
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
- uses: pnpm/setup@v2
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
runtime: node@26.7.0
|
||||
cache: true
|
||||
install: false
|
||||
node-version: 26.7.0
|
||||
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version: 1.4.2
|
||||
|
||||
- run: bun install --frozen-lockfile
|
||||
|
||||
# The TBX file is generated, never committed, so it cannot drift from terms.yaml.
|
||||
# The schema also rejects a malformed entry here, before anything reaches Crowdin.
|
||||
- name: Generate TBX File
|
||||
run: pnpm -F @proj-airi/i18n glossary:build
|
||||
run: bun run --filter @proj-airi/i18n glossary:build
|
||||
|
||||
# NOTICE: Crowdin does not document whether an import merges into the existing
|
||||
# concepts or adds duplicates beside them, and a merge cannot be undone. This
|
||||
|
||||
Reference in New Issue
Block a user