Files
OpenFrontIO/.github/workflows/release.yml
T
Evan 94205426e7 Move turnstile check to api (#3845)
## Description

Re-enables Turnstile verification (was temporarily disabled in v31 to
diagnose intermittent `invalid-input-response` rejections) and moves the
verification call off the game servers.

Game servers no longer hold `TURNSTILE_SECRET_KEY` or hit
`challenges.cloudflare.com` directly. Instead they POST to
`${jwtIssuer}/turnstile` on the api-worker (authenticated with the
existing `apiKey`), which holds the secret and proxies to Cloudflare.
Shrinks blast radius and removes the secret from every game host + GH
Actions workflow.

Response from the api-worker is Zod-validated; null tokens short-circuit
to `rejected` locally.

## Please complete the following:

- [x] I have added screenshots for all UI updates (n/a — server only)
- [x] I process any text displayed to the user through translateText()
(n/a — no user-visible text)
- [ ] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

## Discord:

evanpelle
2026-05-04 12:53:02 -06:00

246 lines
8.9 KiB
YAML

name: 🏷️ Release
on:
release:
types:
- created
- edited
- published
permissions: {}
jobs:
build:
name: 🏗️ Build
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v6
- name: 🔗 Log in to Docker Hub
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ vars.GHCR_USERNAME }}
password: ${{ secrets.GHCR_TOKEN }}
- id: build
env:
GHCR_REPO: openfront-prod
GHCR_USERNAME: ${{ vars.GHCR_USERNAME }}
RELEASE_BODY: ${{ github.event.release.body }}
RELEASE_NAME: ${{ github.event.release.name }}
RELEASE_TAG_NAME: ${{ github.event.release.tag_name }}
ADDITIONAL_VERSION_TAG: ${{ github.event.action == 'published' && 'latest' || '' }}
run: |
set -euxo pipefail
cat <<EOF >> $GITHUB_STEP_SUMMARY
Name: ${RELEASE_NAME}
Tag: ${RELEASE_TAG_NAME}
Changelog:
${RELEASE_BODY}
EOF
./build.sh prod "${RELEASE_TAG_NAME}" "${RELEASE_NAME}" "${RELEASE_BODY}" /tmp/build-metadata.json
IMAGE_ID=$(jq -r '."containerimage.digest"' /tmp/build-metadata.json)
echo "IMAGE_ID=${IMAGE_ID}" >> $GITHUB_OUTPUT
echo "Image ID: \`${IMAGE_ID}\`" >> $GITHUB_STEP_SUMMARY
outputs:
IMAGE_ID: ${{ steps.build.outputs.IMAGE_ID }}
deploy-alpha:
name: 🧪 Deploy to alpha
runs-on: ubuntu-latest
timeout-minutes: 30
needs: [build]
steps:
- uses: actions/checkout@v6
- name: 🔑 Create SSH private key
env:
SERVER_HOST_STAGING: ${{ secrets.SERVER_HOST_STAGING }}
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
run: |
set -euxo pipefail
mkdir -p ~/.ssh
echo "${SSH_PRIVATE_KEY}" > ~/.ssh/id_rsa
test -n "$SERVER_HOST_STAGING" && ssh-keyscan -H "$SERVER_HOST_STAGING" >> ~/.ssh/known_hosts
chmod 600 ~/.ssh/id_rsa
- name: 🚀 Deploy image
env:
GHCR_REPO: openfront-prod
GHCR_USERNAME: ${{ vars.GHCR_USERNAME }}
DOMAIN: ${{ vars.DOMAIN }}
CDN_BASE: ${{ vars.CDN_BASE }}
IMAGE_ID: ${{ needs.build.outputs.IMAGE_ID }}
OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.OTEL_EXPORTER_OTLP_ENDPOINT }}
OTEL_AUTH_HEADER: ${{ secrets.OTEL_AUTH_HEADER }}
API_KEY: ${{ secrets.API_KEY }}
SERVER_HOST_STAGING: ${{ secrets.SERVER_HOST_STAGING }}
SSH_KEY: ~/.ssh/id_rsa
run: |
set -euxo pipefail
bash -x ./deploy.sh staging staging "${IMAGE_ID}" alpha
- name: ⏳ Wait for deployment to start
env:
FQDN: alpha.${{ vars.DOMAIN }}
API_KEY: ${{ secrets.API_KEY }}
run: |
echo "::group::Wait for deployment to start"
set -euxo pipefail
while [ "$(curl -s -H "X-API-Key: ${API_KEY}" https://${FQDN}/commit.txt)" != "${GITHUB_SHA}" ]; do
if [ "$SECONDS" -ge 300 ]; then
echo "Timeout: deployment did not start within 5 minutes"
exit 1
fi
sleep 10
done
echo "Deployment started in ${SECONDS} seconds" >> $GITHUB_STEP_SUMMARY
echo "::endgroup::"
deploy-beta:
name: 🐞 Deploy to beta
runs-on: ubuntu-latest
needs: [build, deploy-alpha]
timeout-minutes: 30
environment: prod-beta
steps:
- uses: actions/checkout@v6
- name: 🔑 Create SSH private key
env:
SERVER_HOST_FALK2: ${{ secrets.SERVER_HOST_FALK2 }}
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
run: |
set -euxo pipefail
mkdir -p ~/.ssh
echo "${SSH_PRIVATE_KEY}" > ~/.ssh/id_rsa
test -n "$SERVER_HOST_FALK2" && ssh-keyscan -H "$SERVER_HOST_FALK2" >> ~/.ssh/known_hosts
chmod 600 ~/.ssh/id_rsa
- name: 🚀 Deploy image
env:
GHCR_REPO: ${{ vars.GHCR_REPO }}
GHCR_USERNAME: ${{ vars.GHCR_USERNAME }}
DOMAIN: ${{ vars.DOMAIN }}
CDN_BASE: ${{ vars.CDN_BASE }}
IMAGE_ID: ${{ needs.build.outputs.IMAGE_ID }}
OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.OTEL_EXPORTER_OTLP_ENDPOINT }}
OTEL_AUTH_HEADER: ${{ secrets.OTEL_AUTH_HEADER }}
API_KEY: ${{ secrets.API_KEY }}
SERVER_HOST_FALK2: ${{ secrets.SERVER_HOST_FALK2 }}
SSH_KEY: ~/.ssh/id_rsa
run: |
set -euxo pipefail
./deploy.sh prod falk2 "${IMAGE_ID}" beta
- name: ⏳ Wait for deployment to start
env:
FQDN: beta.${{ vars.DOMAIN }}
API_KEY: ${{ secrets.API_KEY }}
run: |
echo "::group::Wait for deployment to start"
set -euxo pipefail
while [ "$(curl -s -H "X-API-Key: ${API_KEY}" https://${FQDN}/commit.txt)" != "${GITHUB_SHA}" ]; do
if [ "$SECONDS" -ge 300 ]; then
echo "Timeout: deployment did not start within 5 minutes"
exit 1
fi
sleep 10
done
echo "Deployment started in ${SECONDS} seconds" >> $GITHUB_STEP_SUMMARY
echo "::endgroup::"
deploy-blue:
name: 🔵 Deploy to blue
runs-on: ubuntu-latest
needs: [build, deploy-alpha]
timeout-minutes: 30
environment: prod-blue
steps:
- uses: actions/checkout@v6
- name: 🔑 Create SSH private key
env:
SERVER_HOST_FALK2: ${{ secrets.SERVER_HOST_FALK2 }}
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
run: |
set -euxo pipefail
mkdir -p ~/.ssh
echo "${SSH_PRIVATE_KEY}" > ~/.ssh/id_rsa
test -n "$SERVER_HOST_FALK2" && ssh-keyscan -H "$SERVER_HOST_FALK2" >> ~/.ssh/known_hosts
chmod 600 ~/.ssh/id_rsa
- name: 🚀 Deploy image
env:
GHCR_REPO: ${{ vars.GHCR_REPO }}
GHCR_USERNAME: ${{ vars.GHCR_USERNAME }}
DOMAIN: ${{ vars.DOMAIN }}
CDN_BASE: ${{ vars.CDN_BASE }}
IMAGE_ID: ${{ needs.build.outputs.IMAGE_ID }}
OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.OTEL_EXPORTER_OTLP_ENDPOINT }}
OTEL_AUTH_HEADER: ${{ secrets.OTEL_AUTH_HEADER }}
API_KEY: ${{ secrets.API_KEY }}
SERVER_HOST_FALK2: ${{ secrets.SERVER_HOST_FALK2 }}
SSH_KEY: ~/.ssh/id_rsa
run: |
set -euxo pipefail
./deploy.sh prod falk2 "${IMAGE_ID}" blue
- name: ⏳ Wait for deployment to start
env:
FQDN: blue.${{ vars.DOMAIN }}
API_KEY: ${{ secrets.API_KEY }}
run: |
echo "::group::Wait for deployment to start"
set -euxo pipefail
while [ "$(curl -s -H "X-API-Key: ${API_KEY}" https://${FQDN}/commit.txt)" != "${GITHUB_SHA}" ]; do
if [ "$SECONDS" -ge 300 ]; then
echo "Timeout: deployment did not start within 5 minutes"
exit 1
fi
sleep 10
done
echo "Deployment started in ${SECONDS} seconds" >> $GITHUB_STEP_SUMMARY
echo "::endgroup::"
deploy-green:
name: 🟢 Deploy to green
runs-on: ubuntu-latest
needs: [build, deploy-alpha]
timeout-minutes: 30
environment: prod-green
steps:
- uses: actions/checkout@v6
- name: 🔑 Create SSH private key
env:
SERVER_HOST_FALK2: ${{ secrets.SERVER_HOST_FALK2 }}
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
run: |
set -euxo pipefail
mkdir -p ~/.ssh
echo "${SSH_PRIVATE_KEY}" > ~/.ssh/id_rsa
test -n "$SERVER_HOST_FALK2" && ssh-keyscan -H "$SERVER_HOST_FALK2" >> ~/.ssh/known_hosts
chmod 600 ~/.ssh/id_rsa
- name: 🚀 Deploy image
env:
GHCR_REPO: ${{ vars.GHCR_REPO }}
GHCR_USERNAME: ${{ vars.GHCR_USERNAME }}
DOMAIN: ${{ vars.DOMAIN }}
CDN_BASE: ${{ vars.CDN_BASE }}
IMAGE_ID: ${{ needs.build.outputs.IMAGE_ID }}
OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.OTEL_EXPORTER_OTLP_ENDPOINT }}
OTEL_AUTH_HEADER: ${{ secrets.OTEL_AUTH_HEADER }}
API_KEY: ${{ secrets.API_KEY }}
SERVER_HOST_FALK2: ${{ secrets.SERVER_HOST_FALK2 }}
SSH_KEY: ~/.ssh/id_rsa
run: |
set -euxo pipefail
./deploy.sh prod falk2 "${IMAGE_ID}" green
- name: ⏳ Wait for deployment to start
env:
FQDN: green.${{ vars.DOMAIN }}
API_KEY: ${{ secrets.API_KEY }}
run: |
echo "::group::Wait for deployment to start"
set -euxo pipefail
while [ "$(curl -s -H "X-API-Key: ${API_KEY}" https://${FQDN}/commit.txt)" != "${GITHUB_SHA}" ]; do
if [ "$SECONDS" -ge 300 ]; then
echo "Timeout: deployment did not start within 5 minutes"
exit 1
fi
sleep 10
done
echo "Deployment started in ${SECONDS} seconds" >> $GITHUB_STEP_SUMMARY
echo "::endgroup::"