mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 15:51:42 +00:00
4aa726cfd8
## Description: Add an optional CDN_BASE env var that prefixes hashed asset URLs from asset-manifest.json, so the app can serve static assets from R2/CDN instead of the app origin. The value is determined at runtime via the EJS template (window.CDN_BASE) — empty string means "same origin," matching today's behavior. A hack to load the worker bundle: A same-origin Blob script that dynamic-import()s the cross-origin worker module and buffers early postMessage calls until the imported module's handler attaches, sidestepping the browser's refusal to construct a Worker directly from a cross-origin URL. ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] 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 ## Please put your Discord username so you can be contacted if a bug or regression is found: evan
250 lines
9.2 KiB
YAML
250 lines
9.2 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 }}
|
|
TURNSTILE_SECRET_KEY: ${{ secrets.TURNSTILE_SECRET_KEY }}
|
|
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 }}
|
|
TURNSTILE_SECRET_KEY: ${{ secrets.TURNSTILE_SECRET_KEY }}
|
|
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 }}
|
|
TURNSTILE_SECRET_KEY: ${{ secrets.TURNSTILE_SECRET_KEY }}
|
|
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 }}
|
|
TURNSTILE_SECRET_KEY: ${{ secrets.TURNSTILE_SECRET_KEY }}
|
|
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::"
|