ci: add migration timestamp validation to pipeline

Added a new migrations-lint job to the CI pipeline that validates new migrations
in PRs have timestamps greater than the latest migration on master. This prevents
migration ordering conflicts when multiple PRs add migrations concurrently.

The validation script compares timestamps using git ls-tree for master and
git diff for changed files, outputting GitHub Actions error annotations for
inline PR feedback. The job runs in parallel with other lint/test jobs and
only executes on pull requests.
This commit is contained in:
Deluan 2025-11-24 23:24:33 -05:00
parent 3294bcacfc
commit 201ea993d1
2 changed files with 67 additions and 1 deletions

View File

@ -159,6 +159,20 @@ jobs:
done
- run: ./.github/workflows/validate-translations.sh -v
migrations-lint:
name: Validate migrations
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Fetch master branch
run: git fetch origin master
- name: Validate migration timestamps
run: ./.github/workflows/validate-migrations.sh
check-push-enabled:
name: Check Docker configuration
@ -172,7 +186,8 @@ jobs:
build:
name: Build
needs: [js, go, go-lint, i18n-lint, git-version, check-push-enabled]
needs: [js, go, go-lint, i18n-lint, migrations-lint, git-version, check-push-enabled]
if: ${{ !failure() && !cancelled() }}
strategy:
matrix:
platform: [ linux/amd64, linux/arm64, linux/arm/v5, linux/arm/v6, linux/arm/v7, linux/386, darwin/amd64, darwin/arm64, windows/amd64, windows/386 ]

51
.github/workflows/validate-migrations.sh vendored Executable file
View File

@ -0,0 +1,51 @@
#!/bin/bash
# Validates that new migrations in a PR have timestamps greater than
# the latest migration timestamp on the master branch.
#
# This prevents migration ordering conflicts when multiple PRs add migrations.
set -e
# Get the latest migration timestamp from master branch
# Filter for files matching the pattern: 14-digit timestamp followed by _ and ending in .sql or .go
MASTER_MIGRATIONS=$(git ls-tree --name-only origin/master -- db/migrations/ | grep -E '^db/migrations/[0-9]{14}_.*\.(sql|go)$' || true)
if [ -z "$MASTER_MIGRATIONS" ]; then
echo "No migrations found on master branch"
exit 0
fi
MASTER_LATEST=$(echo "$MASTER_MIGRATIONS" | sed 's|db/migrations/||' | cut -c1-14 | sort -n | tail -1)
# Get migrations added/modified in this PR compared to master
CHANGED_MIGRATIONS=$(git diff --name-only origin/master -- db/migrations/ | grep -E '^db/migrations/[0-9]{14}_.*\.(sql|go)$' || true)
if [ -z "$CHANGED_MIGRATIONS" ]; then
echo "No new migrations found in this PR"
exit 0
fi
echo "Latest migration on master: $MASTER_LATEST"
echo "New/modified migrations in this PR:"
HAS_ERRORS=false
for migration in $CHANGED_MIGRATIONS; do
TIMESTAMP=$(basename "$migration" | cut -c1-14)
echo " - $migration (timestamp: $TIMESTAMP)"
if [ "$TIMESTAMP" -le "$MASTER_LATEST" ]; then
echo "::error file=$migration::Migration timestamp $TIMESTAMP must be greater than latest master timestamp $MASTER_LATEST"
HAS_ERRORS=true
fi
done
if [ "$HAS_ERRORS" = "true" ]; then
echo ""
echo "ERROR: One or more migrations have timestamps that are not after the latest migration on master."
echo "Please regenerate the migration with a newer timestamp using:"
echo " make migration-sql name=your_migration_name"
echo " make migration-go name=your_migration_name"
exit 1
fi
echo "All migration timestamps are valid!"