Skip to content

fix: harden surface reset cascades #2203

fix: harden surface reset cascades

fix: harden surface reset cascades #2203

name: Cloudflare Worker Preview Deploy
on:
pull_request:
paths:
- 'src/**'
- 'worker/**'
- 'public/**'
- 'config.json'
- 'index.html'
- 'package.json'
- 'package-lock.json'
- 'scripts/inject-client-config.js'
- 'vite.config.ts'
- 'tsconfig.json'
- '.github/workflows/cloudflare-web-preview.yml'
- '.github/actions/setup/**'
concurrency:
group: cloudflare-worker-preview-${{ github.event.pull_request.number || github.ref_name }}
cancel-in-progress: true
jobs:
deploy:
if: github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]'
runs-on: ubuntu-latest
environment: preview
permissions:
contents: read
pull-requests: write
env:
CLIENT_CONFIG_OVERRIDES_JSON: ${{ vars.CLIENT_CONFIG_OVERRIDES_JSON }}
CLIENT_CONFIG_OVERRIDES_STRICT: ${{ vars.CLIENT_CONFIG_OVERRIDES_STRICT || 'false' }}
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
- name: Prepare preview metadata
id: metadata
shell: bash
run: |
short_sha="$(git rev-parse --short=7 HEAD)"
{
echo "short_sha=$short_sha"
} >> "$GITHUB_OUTPUT"
- name: Set Sentry build environment for PR preview
if: github.event_name == 'pull_request'
env:
VITE_SENTRY_DSN: ${{ secrets.VITE_SENTRY_DSN }}
VITE_SENTRY_TOOLBAR: 'true'
VITE_SENTRY_ORGANIZATION: ${{ secrets.SENTRY_ORG }}
VITE_SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
shell: bash
run: |
echo "VITE_SENTRY_DSN=$VITE_SENTRY_DSN" >> "$GITHUB_ENV"
echo "VITE_SENTRY_ENVIRONMENT=preview" >> "$GITHUB_ENV"
echo "VITE_SENTRY_PR=${{ github.event.pull_request.number }}" >> "$GITHUB_ENV"
echo "VITE_SENTRY_TOOLBAR=$VITE_SENTRY_TOOLBAR" >> "$GITHUB_ENV"
echo "VITE_SENTRY_ORGANIZATION=$VITE_SENTRY_ORGANIZATION" >> "$GITHUB_ENV"
echo "VITE_SENTRY_PROJECT=$VITE_SENTRY_PROJECT" >> "$GITHUB_ENV"
echo "SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN" >> "$GITHUB_ENV"
echo "SENTRY_ORG=$SENTRY_ORG" >> "$GITHUB_ENV"
echo "SENTRY_PROJECT=$SENTRY_PROJECT" >> "$GITHUB_ENV"
- name: Set build hash
shell: bash
run: |
echo "VITE_BUILD_HASH=${{ steps.metadata.outputs.short_sha }}" >> "$GITHUB_ENV"
- name: Setup app and build
uses: ./.github/actions/setup
with:
build: 'true'
- name: Set deploy alias
id: alias
shell: bash
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
echo "alias=pr-${{ github.event.pull_request.number }}" >> "$GITHUB_OUTPUT"
else
branch="${GITHUB_REF_NAME}"
alias="$(echo "$branch" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/-\+/-/g' | sed 's/^-\|-$//g')"
echo "alias=${alias}" >> "$GITHUB_OUTPUT"
fi
- name: Upload Worker preview
id: deploy
uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0
with:
apiToken: ${{ secrets.TF_CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.TF_VAR_ACCOUNT_ID }}
command: >
versions upload
-c dist/charm/wrangler.json
--preview-alias ${{ steps.alias.outputs.alias }}
--tag ${{ steps.metadata.outputs.short_sha }}
--message ${{ steps.metadata.outputs.short_sha }}
- name: Resolve preview URL
id: preview
env:
DEPLOYMENT_URL: ${{ steps.deploy.outputs.deployment-url }}
COMMAND_OUTPUT: ${{ steps.deploy.outputs.command-output }}
ALIAS: ${{ steps.alias.outputs.alias }}
shell: bash
run: |
alias_url_pattern="^https?://${ALIAS}-[^[:space:]]+$"
preview_url=""
if printf '%s\n' "$DEPLOYMENT_URL" | grep -Eq "$alias_url_pattern"; then
preview_url="$DEPLOYMENT_URL"
else
preview_url="$(printf '%s\n' "$COMMAND_OUTPUT" | grep -Eo "https?://${ALIAS}-[^[:space:]\"'<>)]+" | head -n 1 || true)"
fi
if ! printf '%s\n' "$preview_url" | grep -Eq "$alias_url_pattern"; then
echo "::warning::Failed to resolve aliased Worker preview URL from Wrangler output."
preview_url=""
fi
echo "preview_url=${preview_url}" >> "$GITHUB_OUTPUT"
- name: Publish summary and PR comment
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
MARKER: '<!-- cloudflare-worker-preview -->'
PREVIEW_URL: ${{ steps.preview.outputs.preview_url }}
PREVIEW_ALIAS: ${{ steps.alias.outputs.alias }}
SHORT_SHA: ${{ steps.metadata.outputs.short_sha }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const marker = process.env.MARKER;
const previewUrl = process.env.PREVIEW_URL;
const previewAlias = process.env.PREVIEW_ALIAS;
const shortSha = process.env.SHORT_SHA?.slice(0, 7);
const now = new Date().toUTCString().replace(':00 GMT', ' UTC');
async function publishPrComment(body) {
if (context.eventName !== 'pull_request') return;
try {
const { owner, repo } = context.repo;
const issue_number = context.issue.number;
const comments = await github.paginate(github.rest.issues.listComments, {
owner, repo, issue_number,
});
const existing = comments.find(
(c) => c.user.type === "Bot" && c.body.includes(marker),
);
if (existing) {
await github.rest.issues.deleteComment({
owner, repo, comment_id: existing.id,
});
}
await github.rest.issues.createComment({ owner, repo, issue_number, body });
} catch (error) {
core.warning(`Worker preview uploaded, but the PR comment could not be updated: ${error.message}`);
}
}
if (!previewUrl) {
const message = [
marker,
`## Deploying with &nbsp;<a href="https://workers.dev"><img alt="Cloudflare Workers" src="https://workers.cloudflare.com/logo.svg" width="16"></a> &nbsp;Cloudflare Workers`,
``,
`✅ Worker preview upload completed, but Wrangler did not return a resolvable aliased preview URL.`,
``,
`Alias: \`${previewAlias}\``,
`Commit: \`${shortSha}\``,
`Updated: ${now}`,
].join("\n");
await core.summary.addRaw(message.replace(marker + "\n", "")).write();
await publishPrComment(message);
return;
}
const tableRow = "| ✅ Deployment successful! | <a href='" + previewUrl + "'>" + previewUrl + "</a> | " + shortSha + " | `" + previewAlias + "` | " + now + " |";
const comment = [
marker,
`## Deploying with &nbsp;<a href="https://workers.dev"><img alt="Cloudflare Workers" src="https://workers.cloudflare.com/logo.svg" width="16"></a> &nbsp;Cloudflare Workers`,
``,
`| Status | Preview URL | Commit | Alias | Updated (UTC) |`,
`| - | - | - | - | - |`,
tableRow,
].join("\n");
await core.summary.addRaw(comment.replace(marker + "\n", "")).write();
await publishPrComment(comment);