From 3a5b6e2d518ff497abdf0c9cd50fbf212ac049f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Kucharczyk?= Date: Fri, 12 Jun 2026 17:08:53 +0200 Subject: [PATCH] Add Gitea Actions workflows for staging deployments Branch pushes deploy a per-branch staging instance at tracker-.home.arpa via the NAS act_runner; branch deletion tears it down. build.yml ports the GitHub CI workflow so prod image builds keep running on Gitea now that .gitea/workflows/ exists (Gitea ignores .github/workflows/ when it does). Co-Authored-By: Claude Fable 5 --- .gitea/workflows/build.yml | 48 +++++++++++++++++++++++++++++ .gitea/workflows/staging.yml | 58 ++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 .gitea/workflows/build.yml create mode 100644 .gitea/workflows/staging.yml diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml new file mode 100644 index 0000000..f81b099 --- /dev/null +++ b/.gitea/workflows/build.yml @@ -0,0 +1,48 @@ +name: Django CI/CD + +on: + push: + paths-ignore: [ 'README.md' ] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install uv + uses: astral-sh/setup-uv@v5 + with: + enable-cache: false + python-version: "3.14" + + - name: Install dependencies + run: uv sync --frozen + + - name: Run Migrations + run: uv run python manage.py migrate + + - name: Run Tests + run: uv run --with pytest-django pytest + + build-and-push: + needs: test + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + steps: + - uses: actions/checkout@v4 + + - name: Set Version + run: echo "VERSION_NUMBER=1.7.0" >> $GITHUB_ENV + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and push + uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: | + registry.kucharczyk.xyz/timetracker:latest + registry.kucharczyk.xyz/timetracker:${{ env.VERSION_NUMBER }} diff --git a/.gitea/workflows/staging.yml b/.gitea/workflows/staging.yml new file mode 100644 index 0000000..112e23e --- /dev/null +++ b/.gitea/workflows/staging.yml @@ -0,0 +1,58 @@ +name: Staging deployment + +on: + push: + branches-ignore: [main] + delete: + +jobs: + deploy: + if: github.event_name == 'push' + runs-on: ubuntu-latest + env: + BRANCH: ${{ github.ref_name }} + steps: + - uses: actions/checkout@v4 + + - name: Compute staging name + run: | + SLUG=$(echo "$BRANCH" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9-]+/-/g; s/-+/-/g; s/^-//; s/-$//' | cut -c1-40) + echo "SLUG=${SLUG}" >> "$GITHUB_ENV" + echo "HOST=tracker-${SLUG}.home.arpa" >> "$GITHUB_ENV" + + - name: Build image + run: docker build -t "timetracker:staging-${SLUG}" . + + - name: Deploy staging container + run: | + docker rm -f "timetracker-staging-${SLUG}" 2>/dev/null || true + docker run -d --name "timetracker-staging-${SLUG}" \ + --network docker-compose-templates_public \ + -e TZ=Europe/Prague \ + -e PUID=1000 \ + -e PGID=100 \ + -e DATA_DIR=/home/timetracker/app/data \ + -e "CSRF_TRUSTED_ORIGINS=https://${HOST}" \ + -v "timetracker-staging-${SLUG}:/home/timetracker/app/data" \ + -l "caddy=${HOST}" \ + -l 'caddy.reverse_proxy={{ upstreams 8000 }}' \ + -l xyz.kucharczyk.staging=timetracker \ + -l "xyz.kucharczyk.staging.branch=${BRANCH}" \ + --restart unless-stopped \ + "timetracker:staging-${SLUG}" + + - name: Summary + run: echo "Deployed to https://${HOST}" >> "$GITHUB_STEP_SUMMARY" + + teardown: + if: github.event_name == 'delete' && github.event.ref_type == 'branch' + runs-on: ubuntu-latest + env: + BRANCH: ${{ github.event.ref }} + steps: + - name: Remove staging container, volume, and image + run: | + SLUG=$(echo "$BRANCH" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9-]+/-/g; s/-+/-/g; s/^-//; s/-$//' | cut -c1-40) + docker rm -f "timetracker-staging-${SLUG}" 2>/dev/null || true + docker volume rm "timetracker-staging-${SLUG}" 2>/dev/null || true + docker rmi "timetracker:staging-${SLUG}" 2>/dev/null || true