@@ -244,6 +244,62 @@ jobs:
244244 exit $code
245245 }
246246
247+ - name : Prepare Azure Trusted Signing
248+ if : matrix.platform == 'win'
249+ shell : pwsh
250+ env :
251+ AZURE_TENANT_ID : ${{ secrets.AZURE_TENANT_ID }}
252+ AZURE_CLIENT_ID : ${{ secrets.AZURE_CLIENT_ID }}
253+ AZURE_CLIENT_SECRET : ${{ secrets.AZURE_CLIENT_SECRET }}
254+ AZURE_TRUSTED_SIGNING_ENDPOINT : ${{ secrets.AZURE_TRUSTED_SIGNING_ENDPOINT }}
255+ AZURE_TRUSTED_SIGNING_ACCOUNT_NAME : ${{ secrets.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME }}
256+ AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE_NAME : ${{ secrets.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE_NAME }}
257+ AZURE_TRUSTED_SIGNING_PUBLISHER_NAME : ${{ secrets.AZURE_TRUSTED_SIGNING_PUBLISHER_NAME }}
258+ run : |
259+ $ErrorActionPreference = "Stop"
260+
261+ $requiredSecrets = @(
262+ $env:AZURE_TENANT_ID,
263+ $env:AZURE_CLIENT_ID,
264+ $env:AZURE_CLIENT_SECRET,
265+ $env:AZURE_TRUSTED_SIGNING_ENDPOINT,
266+ $env:AZURE_TRUSTED_SIGNING_ACCOUNT_NAME,
267+ $env:AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE_NAME,
268+ $env:AZURE_TRUSTED_SIGNING_PUBLISHER_NAME
269+ )
270+ if ($requiredSecrets | Where-Object { [string]::IsNullOrWhiteSpace($_) }) {
271+ Write-Host "Azure Trusted Signing disabled; skipping TrustedSigning module preparation."
272+ exit 0
273+ }
274+
275+ Install-PackageProvider `
276+ -Name NuGet `
277+ -MinimumVersion 2.8.5.201 `
278+ -Force `
279+ -Scope CurrentUser
280+
281+ Install-Module `
282+ -Name TrustedSigning `
283+ -MinimumVersion 0.5.0 `
284+ -Force `
285+ -AllowClobber `
286+ -Repository PSGallery `
287+ -Scope CurrentUser
288+
289+ Import-Module TrustedSigning -MinimumVersion 0.5.0 -Force
290+ Get-Command Invoke-TrustedSigning -ErrorAction Stop
291+
292+ $moduleRoots = @(
293+ [System.IO.Path]::Combine([Environment]::GetFolderPath("MyDocuments"), "PowerShell", "Modules"),
294+ [System.IO.Path]::Combine([Environment]::GetFolderPath("MyDocuments"), "WindowsPowerShell", "Modules"),
295+ [System.IO.Path]::Combine($env:ProgramFiles, "PowerShell", "Modules"),
296+ [System.IO.Path]::Combine($env:ProgramFiles, "WindowsPowerShell", "Modules")
297+ )
298+ $modulePathEntries = @($moduleRoots + ($env:PSModulePath -split ";")) |
299+ Where-Object { $_ -and (Test-Path $_) } |
300+ Select-Object -Unique
301+ "PSModulePath=$($modulePathEntries -join ';')" >> $env:GITHUB_ENV
302+
247303 - name : Build desktop artifact
248304 shell : bash
249305 env :
@@ -511,6 +567,90 @@ jobs:
511567 fail_on_unmatched_files : true
512568 token : ${{ steps.app_token.outputs.token }}
513569
570+ deploy_web :
571+ name : Deploy hosted web app
572+ needs : [preflight, release]
573+ if : ${{ !failure() && !cancelled() && needs.preflight.result == 'success' && needs.release.result == 'success' }}
574+ runs-on : blacksmith-8vcpu-ubuntu-2404
575+ timeout-minutes : 10
576+ env :
577+ VERCEL_TOKEN : ${{ secrets.VERCEL_TOKEN }}
578+ VERCEL_ORG_ID : ${{ secrets.VERCEL_ORG_ID }}
579+ VERCEL_PROJECT_ID : ${{ secrets.VERCEL_PROJECT_ID }}
580+ T3CODE_WEB_ROUTER_URL : ${{ vars.T3CODE_WEB_ROUTER_URL }}
581+ T3CODE_WEB_LATEST_DOMAIN : ${{ vars.T3CODE_WEB_LATEST_DOMAIN }}
582+ T3CODE_WEB_NIGHTLY_DOMAIN : ${{ vars.T3CODE_WEB_NIGHTLY_DOMAIN }}
583+ VERCEL_TEAM_SLUG : ${{ vars.VERCEL_TEAM_SLUG }}
584+ steps :
585+ - name : Checkout
586+ uses : actions/checkout@v6
587+ with :
588+ ref : ${{ needs.preflight.outputs.ref }}
589+
590+ - name : Setup Bun
591+ uses : oven-sh/setup-bun@v2
592+ with :
593+ bun-version-file : package.json
594+
595+ - name : Setup Node
596+ uses : actions/setup-node@v6
597+ with :
598+ node-version-file : package.json
599+
600+ - name : Install release tooling dependencies
601+ run : bun install --frozen-lockfile --filter=@t3tools/scripts --filter=@t3tools/web
602+
603+ - name : Align package versions to release version
604+ run : node scripts/update-release-package-versions.ts "${{ needs.preflight.outputs.version }}"
605+
606+ - name : Refresh release lockfile
607+ run : bun install --lockfile-only --ignore-scripts
608+
609+ - name : Deploy and alias channel
610+ shell : bash
611+ run : |
612+ set -euo pipefail
613+
614+ if [[ -z "${VERCEL_TOKEN:-}" || -z "${VERCEL_ORG_ID:-}" || -z "${VERCEL_PROJECT_ID:-}" ]]; then
615+ echo "Missing one or more required Vercel secrets: VERCEL_TOKEN, VERCEL_ORG_ID, VERCEL_PROJECT_ID." >&2
616+ exit 1
617+ fi
618+
619+ router_url="${T3CODE_WEB_ROUTER_URL:-https://app.t3.codes}"
620+ latest_domain="${T3CODE_WEB_LATEST_DOMAIN:-latest.app.t3.codes}"
621+ nightly_domain="${T3CODE_WEB_NIGHTLY_DOMAIN:-nightly.app.t3.codes}"
622+
623+ if [[ "${{ needs.preflight.outputs.release_channel }}" == "stable" ]]; then
624+ channel_domain="$latest_domain"
625+ channel_name="latest"
626+ else
627+ channel_domain="$nightly_domain"
628+ channel_name="nightly"
629+ fi
630+
631+ vercel_scope_args=()
632+ if [[ -n "${VERCEL_TEAM_SLUG:-}" ]]; then
633+ vercel_scope_args=(--scope "$VERCEL_TEAM_SLUG")
634+ fi
635+
636+ echo "Deploying hosted web app for $channel_name channel."
637+ deployment_url="$(
638+ bunx vercel@53.1.1 deploy apps/web \
639+ --prod \
640+ --skip-domain \
641+ --yes \
642+ --token "$VERCEL_TOKEN" \
643+ "${vercel_scope_args[@]}" \
644+ --build-env "APP_VERSION=${{ needs.preflight.outputs.version }}" \
645+ --build-env "VITE_HOSTED_APP_URL=$router_url" \
646+ --build-env "VITE_HOSTED_APP_CHANNEL=$channel_name"
647+ )"
648+
649+ echo "Aliasing $deployment_url to $channel_domain."
650+ bunx vercel@53.1.1 alias set "$deployment_url" "$channel_domain" \
651+ --token "$VERCEL_TOKEN" \
652+ "${vercel_scope_args[@]}"
653+
514654 finalize :
515655 name : Finalize release
516656 if : ${{ !failure() && !cancelled() && needs.preflight.result == 'success' && needs.release.result == 'success' && needs.preflight.outputs.release_channel == 'stable' }}
@@ -595,8 +735,9 @@ jobs:
595735 always() && !cancelled() &&
596736 needs.preflight.result == 'success' &&
597737 needs.release.result == 'success' &&
738+ needs.deploy_web.result == 'success' &&
598739 (needs.finalize.result == 'success' || needs.finalize.result == 'skipped')
599- needs : [preflight, release, finalize]
740+ needs : [preflight, release, deploy_web, finalize]
600741 runs-on : blacksmith-8vcpu-ubuntu-2404
601742 timeout-minutes : 10
602743 steps :
0 commit comments