mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 17:00:16 +00:00
94205426e7
## 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
246 lines
8.9 KiB
YAML
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::"
|