Skip to content

Deploy web

Deploy web #1

Workflow file for this run

name: Deploy web
on:
workflow_dispatch:
permissions:
contents: read
jobs:
deploy:
name: Deploy web to Vercel
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: 22
cache: npm
cache-dependency-path: web/package-lock.json
- name: Deploy web to Vercel
working-directory: web
env:
VERCEL_AUTH_JSON: ${{ secrets.VERCEL_AUTH_JSON }}
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
run: |
test -n "$VERCEL_ORG_ID" || { echo "VERCEL_ORG_ID secret is required for web deploy"; exit 1; }
test -n "$VERCEL_PROJECT_ID" || { echo "VERCEL_PROJECT_ID secret is required for web deploy"; exit 1; }
if [ -n "$VERCEL_AUTH_JSON" ]; then
VERCEL_CONFIG_DIR="$RUNNER_TEMP/vercel"
mkdir -p "$VERCEL_CONFIG_DIR"
printf '%s' "$VERCEL_AUTH_JSON" > "$VERCEL_CONFIG_DIR/auth.json"
env -u VERCEL_TOKEN npx --yes vercel@latest deploy --prod --yes --global-config "$VERCEL_CONFIG_DIR"
else
test -n "$VERCEL_TOKEN" || { echo "VERCEL_AUTH_JSON or VERCEL_TOKEN secret is required for web deploy"; exit 1; }
npx --yes vercel@latest deploy --prod --yes --token="$VERCEL_TOKEN"
fi
- name: Verify live simulation freshness
run: |
node --input-type=module <<'NODE'
import { readFileSync } from "node:fs";
const expected = JSON.parse(readFileSync("web/public/sim/vault_sim.json", "utf8"));
const expectedReportAsOf = expected.reportAsOf;
const expectedFillRows = expected.source?.fillRows;
if (!expectedReportAsOf || !expectedFillRows) {
throw new Error("committed simulation JSON is missing reportAsOf/source.fillRows");
}
let last = {};
for (let attempt = 1; attempt <= 20; attempt += 1) {
const response = await fetch("https://capletfi.vercel.app/sim/vault_sim.json", {
headers: { "cache-control": "no-cache" },
});
if (response.ok) {
const live = await response.json();
last = {
reportAsOf: live.reportAsOf,
fillRows: live.source?.fillRows,
};
if (last.reportAsOf === expectedReportAsOf && last.fillRows === expectedFillRows) {
console.log("CAPLETFI_SIM_DEPLOY_FRESH");
console.log(JSON.stringify({ ...last, attempt }, null, 2));
process.exit(0);
}
}
await new Promise((resolve) => setTimeout(resolve, 15_000));
}
throw new Error(
`live sim ${JSON.stringify(last)} did not match committed ${JSON.stringify({
reportAsOf: expectedReportAsOf,
fillRows: expectedFillRows,
})}`,
);
NODE