From 22f4717677217fb5f0861d42b152ae33b259e504 Mon Sep 17 00:00:00 2001 From: fUS1ONd Date: Wed, 29 Jul 2026 23:12:47 +0000 Subject: [PATCH 1/2] =?UTF-8?q?ci:=20=D0=B3=D0=BE=D0=BD=D1=8F=D1=82=D1=8C?= =?UTF-8?q?=20=D0=B3=D0=B5=D0=B9=D1=82=20=D0=BD=D0=B0=20pull=20request,=20?= =?UTF-8?q?=D0=B0=20=D0=BD=D0=B5=20=D1=82=D0=BE=D0=BB=D1=8C=D0=BA=D0=BE=20?= =?UTF-8?q?=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=20=D0=BC=D0=B5=D1=80=D0=B6=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Тесты запускались только по push в dev, то есть уже после мержа PR: на самом pull request не было ни одной проверки (gh pr checks — «no checks reported»), и падение обнаруживалось на dev, когда образ уже собирался. Гейт вынесен в переиспользуемый workflow_call и вызывается из двух мест: нового ci.yml на pull_request и существующего docker-publish.yml перед публикацией образа. Одно определение вместо двух копий — копии со временем разошлись бы, и получилось бы худшее: PR зелёный, dev красный. Добавлены отмена устаревших прогонов при новом пуше в ветку PR и кэш Tailwind CLI (make gate качает 120 МБ бинарник, цель tailwind-bin пропускает скачивание при наличии файла). Интеграционные тесты (-tags=integration, нужны Postgres и MinIO) в объём не входят — они и раньше не запускались нигде, это отдельная задача. --- .github/workflows/ci.yml | 20 ++++++++++++ .github/workflows/docker-publish.yml | 20 ++---------- .github/workflows/gate.yml | 48 ++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 17 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/gate.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..2f397f3 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,20 @@ +name: CI + +# До появления этого workflow тесты гонялись только по push в dev, то есть уже +# после мержа: сломанный pull request был зелёным до последнего момента, а падение +# обнаруживалось на dev, когда образ уже собирался. +on: + pull_request: + +# Новый пуш в ветку PR отменяет предыдущий прогон — иначе очередь копит проверки +# коммитов, которые уже неактуальны. +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + gate: + uses: ./.github/workflows/gate.yml diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 63c091e..23ec1f3 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -16,24 +16,10 @@ env: IMAGE_NAME: ghcr.io/lecturelog/lecturelog-web jobs: + # Тот же гейт, что и на pull request — единое определение в gate.yml, + # чтобы проверки PR не могли разойтись с тем, что гейтит публикацию образа. gate: - name: Gate - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Go - uses: actions/setup-go@v5 - with: - go-version-file: go.mod - cache: true - - - name: Run gate - run: make gate - - - name: Check generated artifacts - run: git diff --exit-code + uses: ./.github/workflows/gate.yml publish: name: Publish image diff --git a/.github/workflows/gate.yml b/.github/workflows/gate.yml new file mode 100644 index 0000000..e2763a9 --- /dev/null +++ b/.github/workflows/gate.yml @@ -0,0 +1,48 @@ +name: Gate + +# Переиспользуемый workflow: один и тот же прогон вызывается и на pull request, +# и перед публикацией образа. Вынесен отдельно намеренно — если бы проверки PR +# и предпубликационный гейт были описаны двумя копиями, они бы со временем +# разошлись, и получилось бы худшее из возможного: PR зелёный, а dev красный. +on: + workflow_call: + +permissions: + contents: read + +jobs: + gate: + name: Сборка, vet, тесты + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache: true + + # Версия Tailwind CLI живёт в Makefile — берём её оттуда, чтобы ключ кэша + # инвалидировался ровно при обновлении версии, а не при любой правке Makefile. + - name: Определить версию Tailwind CLI + id: tw + run: echo "version=$(grep -m1 '^TAILWIND_VERSION' Makefile | awk '{print $3}')" >> "$GITHUB_OUTPUT" + + # Цель tailwind-bin пропускает скачивание, если бинарь уже на месте, + # поэтому кэш экономит ~120 МБ загрузки на каждом прогоне. + - name: Кэш Tailwind CLI + uses: actions/cache@v4 + with: + path: bin/tailwindcss + key: tailwind-${{ runner.os }}-${{ steps.tw.outputs.version }} + + - name: Прогон гейта + run: make gate + + # make gate перегенерирует templ и Tailwind. Если закоммиченные *_templ.go + # или static/css/app.css расходятся с результатом генерации — падаем здесь: + # в рантайме отдаётся именно закоммиченный артефакт, а не собранный на месте. + - name: Проверка детерминизма артефактов + run: git diff --exit-code From d1f139ea90af2ff5820cf2267a4d013341d65ebd Mon Sep 17 00:00:00 2001 From: fUS1ONd Date: Wed, 29 Jul 2026 23:16:08 +0000 Subject: [PATCH 2/2] =?UTF-8?q?ci:=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20=D1=8D=D0=BA=D1=88=D0=B5=D0=BD=D1=8B=20=D0=B3?= =?UTF-8?q?=D0=B5=D0=B9=D1=82=D0=B0=20=E2=80=94=20Node=2020=20=D0=B1=D0=BE?= =?UTF-8?q?=D0=BB=D1=8C=D1=88=D0=B5=20=D0=BD=D0=B5=20=D0=BF=D0=BE=D0=B4?= =?UTF-8?q?=D0=B4=D0=B5=D1=80=D0=B6=D0=B8=D0=B2=D0=B0=D0=B5=D1=82=D1=81?= =?UTF-8?q?=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit checkout v4→v7, setup-go v5→v7, cache v4→v6. Прогон выдавал предупреждение, что эти экшены нацелены на Node.js 20 и принудительно запускаются на Node.js 24. Экшены docker/* и action-gh-release в publish-джобе намеренно не тронуты: путь публикации образа на pull request не выполняется, проверить его этим PR невозможно, а молча сломать выкат хуже предупреждения. --- .github/workflows/gate.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/gate.yml b/.github/workflows/gate.yml index e2763a9..eeca2cc 100644 --- a/.github/workflows/gate.yml +++ b/.github/workflows/gate.yml @@ -16,10 +16,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Setup Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v7 with: go-version-file: go.mod cache: true @@ -33,7 +33,7 @@ jobs: # Цель tailwind-bin пропускает скачивание, если бинарь уже на месте, # поэтому кэш экономит ~120 МБ загрузки на каждом прогоне. - name: Кэш Tailwind CLI - uses: actions/cache@v4 + uses: actions/cache@v6 with: path: bin/tailwindcss key: tailwind-${{ runner.os }}-${{ steps.tw.outputs.version }}