Files
metube/.github/workflows/main.yml
T
Alex Shnitman 707f700609 ci: update releases in place instead of delete-and-recreate
The same-day rerun path deleted and recreated the release tag within
seconds, which corrupted GitHub's release index (release 2026.07.05 was
hidden from the public list and floated to the top for maintainers).
Replace it with gh release create/edit: force-move the tag in place on
reruns so it matches the rebuilt Docker image, exclude today's tag when
collecting release notes so reruns cover the whole day, and pin the
created tag to the triggering commit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 16:44:52 +03:00

209 lines
6.5 KiB
YAML

name: build
on:
push:
branches:
- 'master'
paths-ignore:
- '**.md'
jobs:
quality-checks:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: lts/*
- name: Enable pnpm
run: corepack enable
- name: Install frontend dependencies
working-directory: ui
run: pnpm install --frozen-lockfile
- name: Run frontend lint
working-directory: ui
run: pnpm run lint
- name: Build frontend
working-directory: ui
run: pnpm run build
- name: Run frontend tests
working-directory: ui
run: pnpm exec ng test --watch=false
env:
CI: true
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Install Python dependencies
run: uv sync --frozen --group dev
- name: Run backend smoke checks
run: python -m compileall app
- name: Run backend tests
run: uv run pytest app/tests/
- name: Run Trivy filesystem scan
uses: aquasecurity/trivy-action@v0.36.0
with:
scan-type: fs
scan-ref: .
format: table
severity: CRITICAL,HIGH
dockerhub-build-push:
needs: quality-checks
runs-on: ubuntu-latest
steps:
-
name: Get current date
id: date
run: echo "date=$(date +'%Y.%m.%d')" >> "$GITHUB_OUTPUT"
-
name: Checkout
uses: actions/checkout@v7
-
name: Set up QEMU
uses: docker/setup-qemu-action@v4
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
-
name: Login to DockerHub
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Login to GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v7
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
build-args: |
VERSION=${{ steps.date.outputs.date }}
tags: |
${{ secrets.DOCKERHUB_REPOSITORY }}:latest
${{ secrets.DOCKERHUB_REPOSITORY }}:${{ steps.date.outputs.date }}
ghcr.io/${{ github.repository }}:latest
ghcr.io/${{ github.repository }}:${{ steps.date.outputs.date }}
dockerhub-sync-readme:
needs: dockerhub-build-push
runs-on: ubuntu-latest
steps:
- name: Sync README
uses: docker://lsiodev/readme-sync:latest
env:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_PASSWORD: ${{ secrets.DOCKERHUB_PASSWORD }}
GIT_REPOSITORY: ${{ github.repository }}
DOCKER_REPOSITORY: ${{ secrets.DOCKERHUB_REPOSITORY }}
GIT_BRANCH: master
with:
entrypoint: node
args: /opt/docker-readme-sync/sync
create-release:
needs: dockerhub-build-push
runs-on: ubuntu-latest
steps:
- name: Get current date
id: date
run: echo "date=$(date +'%Y.%m.%d')" >> $GITHUB_OUTPUT
- name: Checkout
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Get commits since last release
id: commits
env:
DATE: ${{ steps.date.outputs.date }}
run: |
git fetch --tags
# Exclude today's tag: on a same-day rerun the notes must cover the
# whole day, not just the commits since the morning release.
LAST_TAG=$(git tag -l --sort=-version:refname | grep -E '^[0-9]{4}\.[0-9]{2}\.[0-9]{2}$' | grep -v "^${DATE}$" | head -n 1)
if [ -z "$LAST_TAG" ]; then
COMMITS=""
echo "has_commits=false" >> $GITHUB_OUTPUT
else
COMMITS=$(git log ${LAST_TAG}..HEAD --pretty=format:"- %s (%h)" --no-merges)
if [ -z "$COMMITS" ]; then
echo "has_commits=false" >> $GITHUB_OUTPUT
else
echo "has_commits=true" >> $GITHUB_OUTPUT
fi
fi
{
echo 'commits<<EOF'
echo "$COMMITS"
echo EOF
} >> $GITHUB_OUTPUT
- name: Generate release body
id: release_body
env:
DOCKERHUB_REPO: ${{ secrets.DOCKERHUB_REPOSITORY }}
GHCR_REPO: ghcr.io/${{ github.repository }}
DATE: ${{ steps.date.outputs.date }}
HAS_COMMITS: ${{ steps.commits.outputs.has_commits }}
COMMITS: ${{ steps.commits.outputs.commits }}
run: |
{
echo '## Docker Images'
echo ''
echo 'Docker images have been built and pushed:'
echo ''
echo '**Docker Hub:**'
echo "- \`${DOCKERHUB_REPO}:latest\`"
echo "- \`${DOCKERHUB_REPO}:${DATE}\`"
echo ''
echo '**GitHub Container Registry:**'
echo "- \`${GHCR_REPO}:latest\`"
echo "- \`${GHCR_REPO}:${DATE}\`"
if [ "$HAS_COMMITS" = "true" ] && [ -n "$COMMITS" ]; then
echo ''
echo '## Changes'
echo ''
echo "$COMMITS"
fi
} > release_body.txt
- name: Create or update GitHub Release (mark as latest)
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG_NAME: ${{ steps.date.outputs.date }}
run: |
if gh release view "$TAG_NAME" >/dev/null 2>&1; then
echo "Release $TAG_NAME exists; updating."
# Force-move the tag in place so it matches the rebuilt Docker
# image. Never delete+recreate the tag: that corrupts GitHub's
# release index (broke release 2026.07.05).
gh api -X PATCH "repos/${GITHUB_REPOSITORY}/git/refs/tags/${TAG_NAME}" \
-f sha="$GITHUB_SHA" -F force=true
gh release edit "$TAG_NAME" \
--title "Release $TAG_NAME" \
--notes-file release_body.txt \
--latest
else
echo "Release $TAG_NAME does not exist; creating."
gh release create "$TAG_NAME" \
--target "$GITHUB_SHA" \
--title "Release $TAG_NAME" \
--notes-file release_body.txt \
--latest
fi