|
|
|
|
@@ -62,24 +62,115 @@ jobs:
|
|
|
|
|
path: ui/build
|
|
|
|
|
retention-days: 1
|
|
|
|
|
|
|
|
|
|
# ── docker: backend ───────────────────────────────────────────────────────────
|
|
|
|
|
docker-backend:
|
|
|
|
|
name: Docker / backend
|
|
|
|
|
# ── ui: source map upload ─────────────────────────────────────────────────────
|
|
|
|
|
# Commented out — re-enable when GlitchTip source map uploads are needed again.
|
|
|
|
|
#
|
|
|
|
|
# upload-sourcemaps:
|
|
|
|
|
# name: Upload source maps
|
|
|
|
|
# runs-on: ubuntu-latest
|
|
|
|
|
# needs: [check-ui]
|
|
|
|
|
# steps:
|
|
|
|
|
# - name: Compute release version (strip leading v)
|
|
|
|
|
# id: ver
|
|
|
|
|
# run: |
|
|
|
|
|
# V="${{ gitea.ref_name }}"
|
|
|
|
|
# echo "version=${V#v}" >> "$GITHUB_OUTPUT"
|
|
|
|
|
#
|
|
|
|
|
# - name: Download build artifacts
|
|
|
|
|
# uses: actions/download-artifact@v3
|
|
|
|
|
# with:
|
|
|
|
|
# name: ui-build
|
|
|
|
|
# path: build
|
|
|
|
|
#
|
|
|
|
|
# - name: Install sentry-cli
|
|
|
|
|
# run: npm install -g @sentry/cli
|
|
|
|
|
#
|
|
|
|
|
# - name: Inject debug IDs into build artifacts
|
|
|
|
|
# run: sentry-cli sourcemaps inject ./build
|
|
|
|
|
# env:
|
|
|
|
|
# SENTRY_URL: https://errors.libnovel.cc/
|
|
|
|
|
# SENTRY_AUTH_TOKEN: ${{ secrets.GLITCHTIP_AUTH_TOKEN }}
|
|
|
|
|
# SENTRY_ORG: libnovel
|
|
|
|
|
# SENTRY_PROJECT: ui
|
|
|
|
|
#
|
|
|
|
|
# - name: Upload injected build (for docker-ui)
|
|
|
|
|
# uses: actions/upload-artifact@v3
|
|
|
|
|
# with:
|
|
|
|
|
# name: ui-build-injected
|
|
|
|
|
# path: build
|
|
|
|
|
# retention-days: 1
|
|
|
|
|
#
|
|
|
|
|
# - name: Create GlitchTip release
|
|
|
|
|
# run: sentry-cli releases new ${{ steps.ver.outputs.version }}
|
|
|
|
|
# env:
|
|
|
|
|
# SENTRY_URL: https://errors.libnovel.cc/
|
|
|
|
|
# SENTRY_AUTH_TOKEN: ${{ secrets.GLITCHTIP_AUTH_TOKEN }}
|
|
|
|
|
# SENTRY_ORG: libnovel
|
|
|
|
|
# SENTRY_PROJECT: ui
|
|
|
|
|
#
|
|
|
|
|
# - name: Upload source maps to GlitchTip
|
|
|
|
|
# run: sentry-cli sourcemaps upload ./build --release ${{ steps.ver.outputs.version }}
|
|
|
|
|
# env:
|
|
|
|
|
# SENTRY_URL: https://errors.libnovel.cc/
|
|
|
|
|
# SENTRY_AUTH_TOKEN: ${{ secrets.GLITCHTIP_AUTH_TOKEN }}
|
|
|
|
|
# SENTRY_ORG: libnovel
|
|
|
|
|
# SENTRY_PROJECT: ui
|
|
|
|
|
#
|
|
|
|
|
# - name: Finalize GlitchTip release
|
|
|
|
|
# run: sentry-cli releases finalize ${{ steps.ver.outputs.version }}
|
|
|
|
|
# env:
|
|
|
|
|
# SENTRY_URL: https://errors.libnovel.cc/
|
|
|
|
|
# SENTRY_AUTH_TOKEN: ${{ secrets.GLITCHTIP_AUTH_TOKEN }}
|
|
|
|
|
# SENTRY_ORG: libnovel
|
|
|
|
|
# SENTRY_PROJECT: ui
|
|
|
|
|
#
|
|
|
|
|
# - name: Prune old GlitchTip releases (keep latest 10)
|
|
|
|
|
# run: |
|
|
|
|
|
# set -euo pipefail
|
|
|
|
|
# KEEP=10
|
|
|
|
|
# OLD=$(curl -sf \
|
|
|
|
|
# -H "Authorization: Bearer $SENTRY_AUTH_TOKEN" \
|
|
|
|
|
# "$SENTRY_URL/api/0/organizations/$SENTRY_ORG/releases/?project=$SENTRY_PROJECT&per_page=100" \
|
|
|
|
|
# | python3 -c "
|
|
|
|
|
# import sys, json
|
|
|
|
|
# releases = json.load(sys.stdin)
|
|
|
|
|
# for r in releases[$KEEP:]:
|
|
|
|
|
# print(r['version'])
|
|
|
|
|
# " KEEP=$KEEP)
|
|
|
|
|
# for ver in $OLD; do
|
|
|
|
|
# echo "Deleting old release: $ver"
|
|
|
|
|
# sentry-cli releases delete "$ver" || true
|
|
|
|
|
# done
|
|
|
|
|
# env:
|
|
|
|
|
# SENTRY_URL: https://errors.libnovel.cc
|
|
|
|
|
# SENTRY_AUTH_TOKEN: ${{ secrets.GLITCHTIP_AUTH_TOKEN }}
|
|
|
|
|
# SENTRY_ORG: libnovel
|
|
|
|
|
# SENTRY_PROJECT: ui
|
|
|
|
|
|
|
|
|
|
# ── docker: all images in one job (single login) ──────────────────────────────
|
|
|
|
|
# backend, runner, ui, and caddy are built sequentially in one job so Docker
|
|
|
|
|
# Hub only needs to be authenticated once. This also eliminates 3 redundant
|
|
|
|
|
# checkout + setup-buildx + scheduler round-trips compared to separate jobs.
|
|
|
|
|
docker:
|
|
|
|
|
name: Docker
|
|
|
|
|
runs-on: ubuntu-latest
|
|
|
|
|
needs: [test-backend]
|
|
|
|
|
needs: [test-backend, check-ui]
|
|
|
|
|
steps:
|
|
|
|
|
- uses: actions/checkout@v4
|
|
|
|
|
|
|
|
|
|
- uses: docker/setup-buildx-action@v3
|
|
|
|
|
|
|
|
|
|
# Single login — credential is written to ~/.docker/config.json and
|
|
|
|
|
# reused by all subsequent build-push-action steps in this job.
|
|
|
|
|
- name: Log in to Docker Hub
|
|
|
|
|
uses: docker/login-action@v3
|
|
|
|
|
with:
|
|
|
|
|
username: ${{ secrets.DOCKER_USER }}
|
|
|
|
|
password: ${{ secrets.DOCKER_TOKEN }}
|
|
|
|
|
|
|
|
|
|
- name: Docker meta
|
|
|
|
|
id: meta
|
|
|
|
|
# ── backend ──────────────────────────────────────────────────────────────
|
|
|
|
|
- name: Docker meta / backend
|
|
|
|
|
id: meta-backend
|
|
|
|
|
uses: docker/metadata-action@v5
|
|
|
|
|
with:
|
|
|
|
|
images: ${{ secrets.DOCKER_USER }}/libnovel-backend
|
|
|
|
|
@@ -88,38 +179,23 @@ jobs:
|
|
|
|
|
type=semver,pattern={{major}}.{{minor}}
|
|
|
|
|
type=raw,value=latest
|
|
|
|
|
|
|
|
|
|
- name: Build and push
|
|
|
|
|
- name: Build and push / backend
|
|
|
|
|
uses: docker/build-push-action@v6
|
|
|
|
|
with:
|
|
|
|
|
context: backend
|
|
|
|
|
target: backend
|
|
|
|
|
push: true
|
|
|
|
|
tags: ${{ steps.meta.outputs.tags }}
|
|
|
|
|
labels: ${{ steps.meta.outputs.labels }}
|
|
|
|
|
tags: ${{ steps.meta-backend.outputs.tags }}
|
|
|
|
|
labels: ${{ steps.meta-backend.outputs.labels }}
|
|
|
|
|
build-args: |
|
|
|
|
|
VERSION=${{ steps.meta.outputs.version }}
|
|
|
|
|
VERSION=${{ steps.meta-backend.outputs.version }}
|
|
|
|
|
COMMIT=${{ gitea.sha }}
|
|
|
|
|
cache-from: type=registry,ref=${{ secrets.DOCKER_USER }}/libnovel-backend:latest
|
|
|
|
|
cache-to: type=inline
|
|
|
|
|
|
|
|
|
|
# ── docker: runner ────────────────────────────────────────────────────────────
|
|
|
|
|
docker-runner:
|
|
|
|
|
name: Docker / runner
|
|
|
|
|
runs-on: ubuntu-latest
|
|
|
|
|
needs: [test-backend]
|
|
|
|
|
steps:
|
|
|
|
|
- uses: actions/checkout@v4
|
|
|
|
|
|
|
|
|
|
- uses: docker/setup-buildx-action@v3
|
|
|
|
|
|
|
|
|
|
- name: Log in to Docker Hub
|
|
|
|
|
uses: docker/login-action@v3
|
|
|
|
|
with:
|
|
|
|
|
username: ${{ secrets.DOCKER_USER }}
|
|
|
|
|
password: ${{ secrets.DOCKER_TOKEN }}
|
|
|
|
|
|
|
|
|
|
- name: Docker meta
|
|
|
|
|
id: meta
|
|
|
|
|
# ── runner ───────────────────────────────────────────────────────────────
|
|
|
|
|
- name: Docker meta / runner
|
|
|
|
|
id: meta-runner
|
|
|
|
|
uses: docker/metadata-action@v5
|
|
|
|
|
with:
|
|
|
|
|
images: ${{ secrets.DOCKER_USER }}/libnovel-runner
|
|
|
|
|
@@ -128,115 +204,25 @@ jobs:
|
|
|
|
|
type=semver,pattern={{major}}.{{minor}}
|
|
|
|
|
type=raw,value=latest
|
|
|
|
|
|
|
|
|
|
- name: Build and push
|
|
|
|
|
- name: Build and push / runner
|
|
|
|
|
uses: docker/build-push-action@v6
|
|
|
|
|
with:
|
|
|
|
|
context: backend
|
|
|
|
|
target: runner
|
|
|
|
|
push: true
|
|
|
|
|
tags: ${{ steps.meta.outputs.tags }}
|
|
|
|
|
labels: ${{ steps.meta.outputs.labels }}
|
|
|
|
|
tags: ${{ steps.meta-runner.outputs.tags }}
|
|
|
|
|
labels: ${{ steps.meta-runner.outputs.labels }}
|
|
|
|
|
build-args: |
|
|
|
|
|
VERSION=${{ steps.meta.outputs.version }}
|
|
|
|
|
VERSION=${{ steps.meta-runner.outputs.version }}
|
|
|
|
|
COMMIT=${{ gitea.sha }}
|
|
|
|
|
cache-from: type=registry,ref=${{ secrets.DOCKER_USER }}/libnovel-runner:latest
|
|
|
|
|
cache-to: type=inline
|
|
|
|
|
|
|
|
|
|
# ── ui: source map upload ─────────────────────────────────────────────────────
|
|
|
|
|
upload-sourcemaps:
|
|
|
|
|
name: Upload source maps
|
|
|
|
|
runs-on: ubuntu-latest
|
|
|
|
|
needs: [check-ui]
|
|
|
|
|
steps:
|
|
|
|
|
- name: Compute release version (strip leading v)
|
|
|
|
|
id: ver
|
|
|
|
|
run: |
|
|
|
|
|
V="${{ gitea.ref_name }}"
|
|
|
|
|
echo "version=${V#v}" >> "$GITHUB_OUTPUT"
|
|
|
|
|
|
|
|
|
|
- name: Download build artifacts
|
|
|
|
|
# ── ui ───────────────────────────────────────────────────────────────────
|
|
|
|
|
- name: Download ui build artifacts
|
|
|
|
|
uses: actions/download-artifact@v3
|
|
|
|
|
with:
|
|
|
|
|
name: ui-build
|
|
|
|
|
path: build
|
|
|
|
|
|
|
|
|
|
- name: Install sentry-cli
|
|
|
|
|
run: npm install -g @sentry/cli
|
|
|
|
|
|
|
|
|
|
- name: Inject debug IDs into build artifacts
|
|
|
|
|
run: sentry-cli sourcemaps inject ./build
|
|
|
|
|
env:
|
|
|
|
|
SENTRY_URL: https://errors.libnovel.cc/
|
|
|
|
|
SENTRY_AUTH_TOKEN: ${{ secrets.GLITCHTIP_AUTH_TOKEN }}
|
|
|
|
|
SENTRY_ORG: libnovel
|
|
|
|
|
SENTRY_PROJECT: ui
|
|
|
|
|
|
|
|
|
|
- name: Upload injected build (for docker-ui)
|
|
|
|
|
uses: actions/upload-artifact@v3
|
|
|
|
|
with:
|
|
|
|
|
name: ui-build-injected
|
|
|
|
|
path: build
|
|
|
|
|
retention-days: 1
|
|
|
|
|
|
|
|
|
|
- name: Create GlitchTip release
|
|
|
|
|
run: sentry-cli releases new ${{ steps.ver.outputs.version }}
|
|
|
|
|
env:
|
|
|
|
|
SENTRY_URL: https://errors.libnovel.cc/
|
|
|
|
|
SENTRY_AUTH_TOKEN: ${{ secrets.GLITCHTIP_AUTH_TOKEN }}
|
|
|
|
|
SENTRY_ORG: libnovel
|
|
|
|
|
SENTRY_PROJECT: ui
|
|
|
|
|
|
|
|
|
|
- name: Upload source maps to GlitchTip
|
|
|
|
|
run: sentry-cli sourcemaps upload ./build --release ${{ steps.ver.outputs.version }}
|
|
|
|
|
env:
|
|
|
|
|
SENTRY_URL: https://errors.libnovel.cc/
|
|
|
|
|
SENTRY_AUTH_TOKEN: ${{ secrets.GLITCHTIP_AUTH_TOKEN }}
|
|
|
|
|
SENTRY_ORG: libnovel
|
|
|
|
|
SENTRY_PROJECT: ui
|
|
|
|
|
|
|
|
|
|
- name: Finalize GlitchTip release
|
|
|
|
|
run: sentry-cli releases finalize ${{ steps.ver.outputs.version }}
|
|
|
|
|
env:
|
|
|
|
|
SENTRY_URL: https://errors.libnovel.cc/
|
|
|
|
|
SENTRY_AUTH_TOKEN: ${{ secrets.GLITCHTIP_AUTH_TOKEN }}
|
|
|
|
|
SENTRY_ORG: libnovel
|
|
|
|
|
SENTRY_PROJECT: ui
|
|
|
|
|
|
|
|
|
|
- name: Prune old GlitchTip releases (keep latest 10)
|
|
|
|
|
run: |
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
KEEP=10
|
|
|
|
|
OLD=$(curl -sf \
|
|
|
|
|
-H "Authorization: Bearer $SENTRY_AUTH_TOKEN" \
|
|
|
|
|
"$SENTRY_URL/api/0/organizations/$SENTRY_ORG/releases/?project=$SENTRY_PROJECT&per_page=100" \
|
|
|
|
|
| python3 -c "
|
|
|
|
|
import sys, json
|
|
|
|
|
releases = json.load(sys.stdin)
|
|
|
|
|
for r in releases[$KEEP:]:
|
|
|
|
|
print(r['version'])
|
|
|
|
|
" KEEP=$KEEP)
|
|
|
|
|
for ver in $OLD; do
|
|
|
|
|
echo "Deleting old release: $ver"
|
|
|
|
|
sentry-cli releases delete "$ver" || true
|
|
|
|
|
done
|
|
|
|
|
env:
|
|
|
|
|
SENTRY_URL: https://errors.libnovel.cc
|
|
|
|
|
SENTRY_AUTH_TOKEN: ${{ secrets.GLITCHTIP_AUTH_TOKEN }}
|
|
|
|
|
SENTRY_ORG: libnovel
|
|
|
|
|
SENTRY_PROJECT: ui
|
|
|
|
|
|
|
|
|
|
# ── docker: ui ────────────────────────────────────────────────────────────────
|
|
|
|
|
docker-ui:
|
|
|
|
|
name: Docker / ui
|
|
|
|
|
runs-on: ubuntu-latest
|
|
|
|
|
needs: [check-ui, upload-sourcemaps]
|
|
|
|
|
steps:
|
|
|
|
|
- uses: actions/checkout@v4
|
|
|
|
|
|
|
|
|
|
- name: Download injected build (debug IDs already embedded)
|
|
|
|
|
uses: actions/download-artifact@v3
|
|
|
|
|
with:
|
|
|
|
|
name: ui-build-injected
|
|
|
|
|
path: ui/build
|
|
|
|
|
|
|
|
|
|
- name: Allow build/ into Docker context (override .dockerignore)
|
|
|
|
|
@@ -244,16 +230,8 @@ jobs:
|
|
|
|
|
grep -v '^build$' ui/.dockerignore > ui/.dockerignore.tmp
|
|
|
|
|
mv ui/.dockerignore.tmp ui/.dockerignore
|
|
|
|
|
|
|
|
|
|
- uses: docker/setup-buildx-action@v3
|
|
|
|
|
|
|
|
|
|
- name: Log in to Docker Hub
|
|
|
|
|
uses: docker/login-action@v3
|
|
|
|
|
with:
|
|
|
|
|
username: ${{ secrets.DOCKER_USER }}
|
|
|
|
|
password: ${{ secrets.DOCKER_TOKEN }}
|
|
|
|
|
|
|
|
|
|
- name: Docker meta
|
|
|
|
|
id: meta
|
|
|
|
|
- name: Docker meta / ui
|
|
|
|
|
id: meta-ui
|
|
|
|
|
uses: docker/metadata-action@v5
|
|
|
|
|
with:
|
|
|
|
|
images: ${{ secrets.DOCKER_USER }}/libnovel-ui
|
|
|
|
|
@@ -262,38 +240,24 @@ jobs:
|
|
|
|
|
type=semver,pattern={{major}}.{{minor}}
|
|
|
|
|
type=raw,value=latest
|
|
|
|
|
|
|
|
|
|
- name: Build and push
|
|
|
|
|
- name: Build and push / ui
|
|
|
|
|
uses: docker/build-push-action@v6
|
|
|
|
|
with:
|
|
|
|
|
context: ui
|
|
|
|
|
push: true
|
|
|
|
|
tags: ${{ steps.meta.outputs.tags }}
|
|
|
|
|
labels: ${{ steps.meta.outputs.labels }}
|
|
|
|
|
tags: ${{ steps.meta-ui.outputs.tags }}
|
|
|
|
|
labels: ${{ steps.meta-ui.outputs.labels }}
|
|
|
|
|
build-args: |
|
|
|
|
|
BUILD_VERSION=${{ steps.meta.outputs.version }}
|
|
|
|
|
BUILD_VERSION=${{ steps.meta-ui.outputs.version }}
|
|
|
|
|
BUILD_COMMIT=${{ gitea.sha }}
|
|
|
|
|
BUILD_TIME=${{ gitea.event.head_commit.timestamp }}
|
|
|
|
|
PREBUILT=1
|
|
|
|
|
cache-from: type=registry,ref=${{ secrets.DOCKER_USER }}/libnovel-ui:latest
|
|
|
|
|
cache-to: type=inline
|
|
|
|
|
|
|
|
|
|
# ── docker: caddy ─────────────────────────────────────────────────────────────
|
|
|
|
|
docker-caddy:
|
|
|
|
|
name: Docker / caddy
|
|
|
|
|
runs-on: ubuntu-latest
|
|
|
|
|
steps:
|
|
|
|
|
- uses: actions/checkout@v4
|
|
|
|
|
|
|
|
|
|
- uses: docker/setup-buildx-action@v3
|
|
|
|
|
|
|
|
|
|
- name: Log in to Docker Hub
|
|
|
|
|
uses: docker/login-action@v3
|
|
|
|
|
with:
|
|
|
|
|
username: ${{ secrets.DOCKER_USER }}
|
|
|
|
|
password: ${{ secrets.DOCKER_TOKEN }}
|
|
|
|
|
|
|
|
|
|
- name: Docker meta
|
|
|
|
|
id: meta
|
|
|
|
|
# ── caddy ────────────────────────────────────────────────────────────────
|
|
|
|
|
- name: Docker meta / caddy
|
|
|
|
|
id: meta-caddy
|
|
|
|
|
uses: docker/metadata-action@v5
|
|
|
|
|
with:
|
|
|
|
|
images: ${{ secrets.DOCKER_USER }}/libnovel-caddy
|
|
|
|
|
@@ -302,13 +266,13 @@ jobs:
|
|
|
|
|
type=semver,pattern={{major}}.{{minor}}
|
|
|
|
|
type=raw,value=latest
|
|
|
|
|
|
|
|
|
|
- name: Build and push
|
|
|
|
|
- name: Build and push / caddy
|
|
|
|
|
uses: docker/build-push-action@v6
|
|
|
|
|
with:
|
|
|
|
|
context: caddy
|
|
|
|
|
push: true
|
|
|
|
|
tags: ${{ steps.meta.outputs.tags }}
|
|
|
|
|
labels: ${{ steps.meta.outputs.labels }}
|
|
|
|
|
tags: ${{ steps.meta-caddy.outputs.tags }}
|
|
|
|
|
labels: ${{ steps.meta-caddy.outputs.labels }}
|
|
|
|
|
cache-from: type=registry,ref=${{ secrets.DOCKER_USER }}/libnovel-caddy:latest
|
|
|
|
|
cache-to: type=inline
|
|
|
|
|
|
|
|
|
|
@@ -316,7 +280,7 @@ jobs:
|
|
|
|
|
release:
|
|
|
|
|
name: Gitea Release
|
|
|
|
|
runs-on: ubuntu-latest
|
|
|
|
|
needs: [docker-backend, docker-runner, docker-ui, docker-caddy, upload-sourcemaps]
|
|
|
|
|
needs: [docker]
|
|
|
|
|
steps:
|
|
|
|
|
- uses: actions/checkout@v4
|
|
|
|
|
with:
|
|
|
|
|
|