| ... | ... | @@ -948,12 +948,20 @@ jobs: |
| 948 | 948 | secrets: |
| 949 | 949 | AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }} |
| 950 | 950 | |
| 951 | | deploy_web: |
| 952 | | name: Deploy hosted web app |
| 953 | | needs: [preflight, relay_public_config, release] |
| 954 | | if: ${{ !failure() && !cancelled() && needs.preflight.result == 'success' && needs.relay_public_config.result == 'success' && needs.release.result == 'success' && needs.preflight.outputs.release_channel != 'preview' }} |
| 951 | # Vercel builds the hosted web app while the desktop jobs run. `--skip-domain` |
| 952 | # keeps the custom domains (the channel and router domains) on the previous |
| 953 | # deployment until deploy_web aliases them, after the GitHub Release. It does |
| 954 | # still move the project's own *.vercel.app production hostname at build time. |
| 955 | # That hostname sits behind Vercel SSO and is not a user channel, so the |
| 956 | # npm-before-client order in docs/operations/release.md holds for users. |
| 957 | build_web: |
| 958 | name: Build hosted web app |
| 959 | needs: [preflight, relay_public_config] |
| 960 | if: ${{ !cancelled() && needs.preflight.result == 'success' && needs.relay_public_config.result == 'success' && needs.preflight.outputs.release_channel != 'preview' }} |
| 955 | 961 | runs-on: blacksmith-8vcpu-ubuntu-2404 |
| 956 | 962 | timeout-minutes: 10 |
| 963 | outputs: |
| 964 | deployment_url: ${{ steps.deploy.outputs.deployment_url }} |
| 957 | 965 | env: |
| 958 | 966 | T3CODE_CLERK_PUBLISHABLE_KEY: ${{ needs.relay_public_config.outputs.clerk_publishable_key }} |
| 959 | 967 | T3CODE_CLERK_JWT_TEMPLATE: ${{ needs.relay_public_config.outputs.clerk_jwt_template }} |
| ... | ... | @@ -963,8 +971,6 @@ jobs: |
| 963 | 971 | VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} |
| 964 | 972 | VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }} |
| 965 | 973 | T3CODE_WEB_ROUTER_URL: ${{ vars.T3CODE_WEB_ROUTER_URL }} |
| 966 | | T3CODE_WEB_LATEST_DOMAIN: ${{ vars.T3CODE_WEB_LATEST_DOMAIN }} |
| 967 | | T3CODE_WEB_NIGHTLY_DOMAIN: ${{ vars.T3CODE_WEB_NIGHTLY_DOMAIN }} |
| 968 | 974 | VERCEL_TEAM_SLUG: ${{ vars.VERCEL_TEAM_SLUG }} |
| 969 | 975 | steps: |
| 970 | 976 | - name: Checkout |
| ... | ... | @@ -1006,7 +1012,8 @@ jobs: |
| 1006 | 1012 | - name: Refresh release lockfile |
| 1007 | 1013 | run: vp install --lockfile-only --ignore-scripts |
| 1008 | 1014 | |
| 1009 | | - name: Deploy and alias channel |
| 1015 | - id: deploy |
| 1016 | name: Build staged deployment |
| 1010 | 1017 | shell: bash |
| 1011 | 1018 | run: | |
| 1012 | 1019 | set -euo pipefail |
| ... | ... | @@ -1017,24 +1024,13 @@ jobs: |
| 1017 | 1024 | fi |
| 1018 | 1025 | |
| 1019 | 1026 | router_url="${T3CODE_WEB_ROUTER_URL:-https://app.t3.codes}" |
| 1020 | | latest_domain="${T3CODE_WEB_LATEST_DOMAIN:-latest.app.t3.codes}" |
| 1021 | | nightly_domain="${T3CODE_WEB_NIGHTLY_DOMAIN:-nightly.app.t3.codes}" |
| 1022 | | router_domain="${router_url#http://}" |
| 1023 | | router_domain="${router_domain#https://}" |
| 1024 | | router_domain="${router_domain%%/*}" |
| 1025 | | |
| 1026 | 1027 | if [[ "${{ needs.preflight.outputs.release_channel }}" == "stable" ]]; then |
| 1027 | | channel_domain="$latest_domain" |
| 1028 | 1028 | channel_name="latest" |
| 1029 | 1029 | else |
| 1030 | | channel_domain="$nightly_domain" |
| 1031 | 1030 | channel_name="nightly" |
| 1032 | 1031 | fi |
| 1033 | 1032 | |
| 1034 | | vercel_scope="${VERCEL_TEAM_SLUG:-$VERCEL_ORG_ID}" |
| 1035 | | vercel_scope_args=(--scope "$vercel_scope") |
| 1036 | | |
| 1037 | | echo "Deploying hosted web app for $channel_name channel." |
| 1033 | echo "Building hosted web app for $channel_name channel." |
| 1038 | 1034 | deployment_url="$( |
| 1039 | 1035 | vp dlx vercel@53.1.1 deploy \ |
| 1040 | 1036 | --archive=tgz \ |
| ... | ... | @@ -1042,7 +1038,7 @@ jobs: |
| 1042 | 1038 | --skip-domain \ |
| 1043 | 1039 | --yes \ |
| 1044 | 1040 | --token "$VERCEL_TOKEN" \ |
| 1045 | | "${vercel_scope_args[@]}" \ |
| 1041 | --scope "${VERCEL_TEAM_SLUG:-$VERCEL_ORG_ID}" \ |
| 1046 | 1042 | --build-env "APP_VERSION=${{ needs.preflight.outputs.version }}" \ |
| 1047 | 1043 | --build-env "T3CODE_CLERK_PUBLISHABLE_KEY=${T3CODE_CLERK_PUBLISHABLE_KEY:-}" \ |
| 1048 | 1044 | --build-env "T3CODE_CLERK_JWT_TEMPLATE=${T3CODE_CLERK_JWT_TEMPLATE:-}" \ |
| ... | ... | @@ -1054,25 +1050,92 @@ jobs: |
| 1054 | 1050 | --build-env "VITE_HOSTED_APP_URL=$router_url" \ |
| 1055 | 1051 | --build-env "VITE_HOSTED_APP_CHANNEL=$channel_name" |
| 1056 | 1052 | )" |
| 1053 | echo "Staged $deployment_url." |
| 1054 | echo "deployment_url=$deployment_url" >> "$GITHUB_OUTPUT" |
| 1057 | 1055 | |
| 1058 | | echo "Aliasing $deployment_url to $channel_domain." |
| 1059 | | vp dlx vercel@53.1.1 alias set "$deployment_url" "$channel_domain" \ |
| 1056 | deploy_web: |
| 1057 | name: Deploy hosted web app |
| 1058 | needs: [preflight, build_web, release] |
| 1059 | if: ${{ !failure() && !cancelled() && needs.preflight.result == 'success' && needs.build_web.result == 'success' && needs.release.result == 'success' && needs.preflight.outputs.release_channel != 'preview' }} |
| 1060 | runs-on: blacksmith-2vcpu-ubuntu-2404 |
| 1061 | timeout-minutes: 10 |
| 1062 | env: |
| 1063 | DEPLOYMENT_URL: ${{ needs.build_web.outputs.deployment_url }} |
| 1064 | VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} |
| 1065 | VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} |
| 1066 | VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }} |
| 1067 | T3CODE_WEB_ROUTER_URL: ${{ vars.T3CODE_WEB_ROUTER_URL }} |
| 1068 | T3CODE_WEB_LATEST_DOMAIN: ${{ vars.T3CODE_WEB_LATEST_DOMAIN }} |
| 1069 | T3CODE_WEB_NIGHTLY_DOMAIN: ${{ vars.T3CODE_WEB_NIGHTLY_DOMAIN }} |
| 1070 | VERCEL_TEAM_SLUG: ${{ vars.VERCEL_TEAM_SLUG }} |
| 1071 | steps: |
| 1072 | - name: Checkout |
| 1073 | uses: actions/checkout@v6 |
| 1074 | with: |
| 1075 | ref: ${{ needs.preflight.outputs.ref }} |
| 1076 | sparse-checkout: | |
| 1077 | /* |
| 1078 | !/.repos/ |
| 1079 | sparse-checkout-cone-mode: false |
| 1080 | |
| 1081 | - name: Setup Vite+ |
| 1082 | uses: voidzero-dev/setup-vp@v1 |
| 1083 | with: |
| 1084 | node-version-file: package.json |
| 1085 | cache: false |
| 1086 | run-install: false |
| 1087 | |
| 1088 | - name: Alias channel |
| 1089 | shell: bash |
| 1090 | run: | |
| 1091 | set -euo pipefail |
| 1092 | |
| 1093 | if [[ -z "$DEPLOYMENT_URL" ]]; then |
| 1094 | echo "Build hosted web app did not report a deployment URL." >&2 |
| 1095 | exit 1 |
| 1096 | fi |
| 1097 | |
| 1098 | router_url="${T3CODE_WEB_ROUTER_URL:-https://app.t3.codes}" |
| 1099 | latest_domain="${T3CODE_WEB_LATEST_DOMAIN:-latest.app.t3.codes}" |
| 1100 | nightly_domain="${T3CODE_WEB_NIGHTLY_DOMAIN:-nightly.app.t3.codes}" |
| 1101 | router_domain="${router_url#http://}" |
| 1102 | router_domain="${router_domain#https://}" |
| 1103 | router_domain="${router_domain%%/*}" |
| 1104 | |
| 1105 | if [[ "${{ needs.preflight.outputs.release_channel }}" == "stable" ]]; then |
| 1106 | channel_domain="$latest_domain" |
| 1107 | channel_name="latest" |
| 1108 | else |
| 1109 | channel_domain="$nightly_domain" |
| 1110 | channel_name="nightly" |
| 1111 | fi |
| 1112 | |
| 1113 | vercel_scope_args=(--scope "${VERCEL_TEAM_SLUG:-$VERCEL_ORG_ID}") |
| 1114 | |
| 1115 | echo "Aliasing $DEPLOYMENT_URL to $channel_domain." |
| 1116 | vp dlx vercel@53.1.1 alias set "$DEPLOYMENT_URL" "$channel_domain" \ |
| 1060 | 1117 | --token "$VERCEL_TOKEN" \ |
| 1061 | 1118 | "${vercel_scope_args[@]}" |
| 1062 | 1119 | |
| 1063 | 1120 | if [[ "$channel_name" == "latest" && -n "$router_domain" && "$router_domain" != "$channel_domain" ]]; then |
| 1064 | | echo "Aliasing $deployment_url to router domain $router_domain." |
| 1065 | | vp dlx vercel@53.1.1 alias set "$deployment_url" "$router_domain" \ |
| 1121 | echo "Aliasing $DEPLOYMENT_URL to router domain $router_domain." |
| 1122 | vp dlx vercel@53.1.1 alias set "$DEPLOYMENT_URL" "$router_domain" \ |
| 1066 | 1123 | --token "$VERCEL_TOKEN" \ |
| 1067 | 1124 | "${vercel_scope_args[@]}" |
| 1068 | 1125 | fi |
| 1069 | 1126 | |
| 1070 | | deploy_marketing: |
| 1071 | | name: Deploy marketing site |
| 1072 | | needs: [preflight, release] |
| 1073 | | if: ${{ !failure() && !cancelled() && needs.preflight.result == 'success' && needs.release.result == 'success' && needs.preflight.outputs.release_channel == 'nightly' }} |
| 1127 | # Same split as the web app: build a production deployment early, then |
| 1128 | # promote it to t3.codes once the release it links to exists. As above, the |
| 1129 | # project's own *.vercel.app hostname moves at build time. |
| 1130 | build_marketing: |
| 1131 | name: Build marketing site |
| 1132 | needs: [preflight] |
| 1133 | if: ${{ !cancelled() && needs.preflight.result == 'success' && needs.preflight.outputs.release_channel == 'nightly' }} |
| 1074 | 1134 | runs-on: blacksmith-8vcpu-ubuntu-2404 |
| 1075 | 1135 | timeout-minutes: 10 |
| 1136 | outputs: |
| 1137 | deployment_url: ${{ steps.deploy.outputs.deployment_url }} |
| 1138 | project_id: ${{ steps.deploy.outputs.project_id }} |
| 1076 | 1139 | env: |
| 1077 | 1140 | VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} |
| 1078 | 1141 | VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} |
| ... | ... | @@ -1096,7 +1159,8 @@ jobs: |
| 1096 | 1159 | args: |
| 1097 | 1160 | - --filter=@t3tools/marketing... |
| 1098 | 1161 | |
| 1099 | | - name: Deploy marketing site to Vercel |
| 1162 | - id: deploy |
| 1163 | name: Build staged deployment |
| 1100 | 1164 | shell: bash |
| 1101 | 1165 | run: | |
| 1102 | 1166 | set -euo pipefail |
| ... | ... | @@ -1114,9 +1178,60 @@ jobs: |
| 1114 | 1178 | )" |
| 1115 | 1179 | export VERCEL_PROJECT_ID |
| 1116 | 1180 | |
| 1117 | | vp dlx vercel@53.1.1 deploy \ |
| 1118 | | --archive=tgz \ |
| 1119 | | --prod \ |
| 1181 | deployment_url="$( |
| 1182 | vp dlx vercel@53.1.1 deploy \ |
| 1183 | --archive=tgz \ |
| 1184 | --prod \ |
| 1185 | --skip-domain \ |
| 1186 | --yes \ |
| 1187 | --token "$VERCEL_TOKEN" \ |
| 1188 | --scope "${VERCEL_TEAM_SLUG:-$VERCEL_ORG_ID}" |
| 1189 | )" |
| 1190 | echo "Staged $deployment_url." |
| 1191 | echo "deployment_url=$deployment_url" >> "$GITHUB_OUTPUT" |
| 1192 | echo "project_id=$VERCEL_PROJECT_ID" >> "$GITHUB_OUTPUT" |
| 1193 | |
| 1194 | deploy_marketing: |
| 1195 | name: Deploy marketing site |
| 1196 | needs: [preflight, build_marketing, release] |
| 1197 | if: ${{ !failure() && !cancelled() && needs.preflight.result == 'success' && needs.build_marketing.result == 'success' && needs.release.result == 'success' && needs.preflight.outputs.release_channel == 'nightly' }} |
| 1198 | runs-on: blacksmith-2vcpu-ubuntu-2404 |
| 1199 | timeout-minutes: 10 |
| 1200 | env: |
| 1201 | DEPLOYMENT_URL: ${{ needs.build_marketing.outputs.deployment_url }} |
| 1202 | VERCEL_PROJECT_ID: ${{ needs.build_marketing.outputs.project_id }} |
| 1203 | VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} |
| 1204 | VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} |
| 1205 | VERCEL_TEAM_SLUG: ${{ vars.VERCEL_TEAM_SLUG }} |
| 1206 | steps: |
| 1207 | - name: Checkout |
| 1208 | uses: actions/checkout@v6 |
| 1209 | with: |
| 1210 | ref: ${{ needs.preflight.outputs.ref }} |
| 1211 | sparse-checkout: | |
| 1212 | /* |
| 1213 | !/.repos/ |
| 1214 | sparse-checkout-cone-mode: false |
| 1215 | |
| 1216 | - name: Setup Vite+ |
| 1217 | uses: voidzero-dev/setup-vp@v1 |
| 1218 | with: |
| 1219 | node-version-file: package.json |
| 1220 | cache: false |
| 1221 | run-install: false |
| 1222 | |
| 1223 | - name: Promote marketing site |
| 1224 | shell: bash |
| 1225 | run: | |
| 1226 | set -euo pipefail |
| 1227 | |
| 1228 | if [[ -z "$DEPLOYMENT_URL" ]]; then |
| 1229 | echo "Build marketing site did not report a deployment URL." >&2 |
| 1230 | exit 1 |
| 1231 | fi |
| 1232 | |
| 1233 | echo "Promoting $DEPLOYMENT_URL." |
| 1234 | vp dlx vercel@53.1.1 promote "$DEPLOYMENT_URL" \ |
| 1120 | 1235 | --yes \ |
| 1121 | 1236 | --token "$VERCEL_TOKEN" \ |
| 1122 | 1237 | --scope "${VERCEL_TEAM_SLUG:-$VERCEL_ORG_ID}" |