Skip to content

deps(backend): bump pillow from 11.0.0 to 12.2.0 in /backend #45

deps(backend): bump pillow from 11.0.0 to 12.2.0 in /backend

deps(backend): bump pillow from 11.0.0 to 12.2.0 in /backend #45

Workflow file for this run

name: ci
on:
push:
branches: [main]
tags: ["v*"]
pull_request:
workflow_dispatch:
permissions:
contents: write # release job needs to create GitHub Releases
packages: write
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
# ----- Backend -----------------------------------------------------------
backend:
runs-on: ubuntu-latest
defaults:
run:
working-directory: backend
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
with:
python-version: "3.12"
cache: pip
cache-dependency-path: backend/requirements.txt
- run: pip install -r requirements.txt
- name: Django system checks
env:
DJANGO_SECRET_KEY: ci-only
DJANGO_DEBUG: "false"
run: python manage.py check
- name: Run tests
env:
DJANGO_SECRET_KEY: ci-only
DJANGO_DEBUG: "false"
run: python manage.py test --noinput --verbosity 2
# ----- Frontend ----------------------------------------------------------
frontend:
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontend
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: "22"
cache: npm
cache-dependency-path: frontend/package-lock.json
- run: npm ci
- run: npm run lint
- run: npx vue-tsc --noEmit
- run: npm run build
- name: i18n parity (en/fr key counts match)
run: |
python3 - <<'PY'
import json, sys
en = json.load(open('src/locales/en.json'))
fr = json.load(open('src/locales/fr.json'))
def keys(d, p=''):
out = set()
for k, v in d.items():
q = f'{p}.{k}' if p else k
out |= keys(v, q) if isinstance(v, dict) else {q}
return out
en_k, fr_k = keys(en), keys(fr)
if en_k != fr_k:
missing_in_fr = en_k - fr_k
missing_in_en = fr_k - en_k
print(f"locale parity FAILED. en={len(en_k)}, fr={len(fr_k)}")
if missing_in_fr: print("missing in fr:", sorted(missing_in_fr)[:20])
if missing_in_en: print("missing in en:", sorted(missing_in_en)[:20])
sys.exit(1)
print(f"locale parity OK ({len(en_k)} keys)")
PY
# ----- Docker image ------------------------------------------------------
# Publish to GHCR ONLY on tag v* — every release goes through an explicit
# ``git tag vX.Y.Z`` so the registry never holds untagged main-branch builds.
# PRs and main pushes still run backend+frontend for lint/test feedback;
# they just don't produce an image.
docker:
needs: [backend, frontend]
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v')
steps:
- uses: actions/checkout@v5
- uses: docker/setup-qemu-action@v4
- uses: docker/setup-buildx-action@v4
- name: Log in to GHCR
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Compute image tags
id: meta
uses: docker/metadata-action@v6
with:
images: ghcr.io/${{ github.repository_owner }}/hostcraft
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest
- name: Build & push multi-arch image
uses: docker/build-push-action@v7
with:
context: .
file: backend/Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
# ----- GitHub Release ---------------------------------------------------
# Every published image gets a matching GitHub Release. The job is gated
# on a successful image build, so the registry and the Releases page can
# never drift: if an image is published, its release exists; if it
# doesn't, neither does.
#
# Notes come from the tag annotation (``git tag -a vX.Y.Z -m "..."``)
# when present, otherwise we let GitHub auto-generate from the commit
# history since the previous tag.
release:
needs: [docker]
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v')
permissions:
contents: write
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0 # need full history for `git tag -l`
- name: Create GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
VERSION="${GITHUB_REF_NAME}"
ANNOTATION="$(git tag -l --format='%(contents)' "$VERSION")"
IMAGE="ghcr.io/${{ github.repository_owner }}/hostcraft:${VERSION}"
FOOTER=$(cat <<EOF
---
Container image: \`${IMAGE}\` (also tagged \`:${VERSION#v}\`, \`:latest\`).
EOF
)
if [ -n "$ANNOTATION" ]; then
printf '%s\n%s' "$ANNOTATION" "$FOOTER" > /tmp/notes.md
gh release create "$VERSION" \
--title "$VERSION" \
--notes-file /tmp/notes.md
else
gh release create "$VERSION" \
--title "$VERSION" \
--generate-notes \
--notes "$FOOTER"
fi