ci: optimize build + deploy + migrate workflows
CI / CI (pull_request) Successful in 31m18s

- build.yaml: merge 3 cargo steps into single compile pass (reuse artifacts)
- build.yaml: remove cargo clean (wasted compiled artifacts before Docker)
- build.yaml: add secret validation for registry credentials
- deploy.yaml: skip checkout, fetch SHA via Gitea API (no clone overhead)
- deploy.yaml: reuse FORGEJO_REGISTRY_TOKEN for API auth (existing privilege)
- deploy.yaml: validate SHA image exists before tagging as latest
- deploy.yaml: add secret validation for registry credentials
- migrate.yaml: merge schema verification into both changed + manual paths
- migrate.yaml: manual trigger now fails on first error (was silently masking)
This commit is contained in:
2026-09-13 09:53:11 +09:00
parent c142ff5109
commit 4fdbb48ae6
3 changed files with 52 additions and 26 deletions
+9 -11
View File
@@ -26,17 +26,11 @@ jobs:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Cargo build all - name: Cargo build, test, clippy (single compile pass)
run: cargo build --all --verbose run: |
cargo build --all --verbose
- name: Cargo test all cargo test --all --lib --verbose 2>&1 | tail -150 || true
run: cargo test --all --lib --verbose 2>&1 | tail -150 || true cargo clippy --all --all-targets -- -D warnings 2>&1 | tail -50 || true
- name: Cargo clippy
run: cargo clippy --all --all-targets -- -D warnings 2>&1 | tail -50 || true
- name: Clean build artifacts before Docker
run: cargo clean
- name: Get short SHA - name: Get short SHA
id: sha id: sha
@@ -44,6 +38,10 @@ jobs:
- name: Registry login - name: Registry login
run: | run: |
if [ -z "${REGISTRY_USER}" ] || [ -z "${REGISTRY_TOKEN}" ]; then
echo "ERROR: Missing REGISTRY_USER or REGISTRY_TOKEN secrets"
exit 1
fi
echo "${REGISTRY_TOKEN}" | docker login "${REGISTRY}" \ echo "${REGISTRY_TOKEN}" | docker login "${REGISTRY}" \
--username "${REGISTRY_USER}" --password-stdin --username "${REGISTRY_USER}" --password-stdin
env: env:
+30 -11
View File
@@ -15,29 +15,48 @@ jobs:
name: Tag & Push Latest name: Tag & Push Latest
runs-on: rust runs-on: rust
steps: steps:
- name: Install Docker - name: Install Docker and curl
run: apt-get update && apt-get install -y docker.io run: apt-get update && apt-get install -y docker.io curl
- name: Checkout code - name: Get short SHA via Gitea API
uses: actions/checkout@v4
- name: Get short SHA
id: sha id: sha
run: echo "short_sha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT run: |
# Fetch latest commit SHA for main branch from Gitea API
COMMIT_SHA=$(curl -s -H "Authorization: token ${REGISTRY_TOKEN}" \
"https://forgejo.riotpiao.com/api/v1/repos/riotpiao-poimen/poimen-memory/commits?sha=main&limit=1" | \
grep -o '"sha":"[^"]*' | head -1 | cut -d'"' -f4)
if [ -z "$COMMIT_SHA" ]; then
echo "ERROR: Failed to fetch commit SHA from Gitea API"
exit 1
fi
SHORT_SHA=$(echo "$COMMIT_SHA" | cut -c1-7)
echo "short_sha=$SHORT_SHA" >> $GITHUB_OUTPUT
echo "Full SHA: $COMMIT_SHA, Short: $SHORT_SHA"
env:
REGISTRY_TOKEN: ${{ secrets.FORGEJO_REGISTRY_TOKEN }}
- name: Registry login - name: Registry login
run: | run: |
if [ -z "${REGISTRY_USER}" ] || [ -z "${REGISTRY_TOKEN}" ]; then
echo "ERROR: Missing REGISTRY_USER or REGISTRY_TOKEN secrets"
exit 1
fi
echo "${REGISTRY_TOKEN}" | docker login "${REGISTRY}" \ echo "${REGISTRY_TOKEN}" | docker login "${REGISTRY}" \
--username "${REGISTRY_USER}" --password-stdin --username "${REGISTRY_USER}" --password-stdin
env: env:
REGISTRY_USER: ${{ secrets.FORGEJO_REGISTRY_USER }} REGISTRY_USER: ${{ secrets.FORGEJO_REGISTRY_USER }}
REGISTRY_TOKEN: ${{ secrets.FORGEJO_REGISTRY_TOKEN }} REGISTRY_TOKEN: ${{ secrets.FORGEJO_REGISTRY_TOKEN }}
- name: Pull SHA image and tag as latest - name: Verify SHA image exists, tag as latest
run: | run: |
docker pull "${IMAGE}:${{ steps.sha.outputs.short_sha }}" && \ if ! docker pull "${IMAGE}:${{ steps.sha.outputs.short_sha }}"; then
docker tag "${IMAGE}:${{ steps.sha.outputs.short_sha }}" "${IMAGE}:latest" && \ echo "ERROR: Image ${IMAGE}:${{ steps.sha.outputs.short_sha }} not found. Check build.yaml passed."
docker push "${IMAGE}:latest" && \ exit 1
fi
docker tag "${IMAGE}:${{ steps.sha.outputs.short_sha }}" "${IMAGE}:latest"
docker push "${IMAGE}:latest"
echo "Tagged and pushed: ${IMAGE}:latest (from ${{ steps.sha.outputs.short_sha }})" echo "Tagged and pushed: ${IMAGE}:latest (from ${{ steps.sha.outputs.short_sha }})"
- name: Prune images - name: Prune images
+13 -4
View File
@@ -31,7 +31,7 @@ jobs:
echo "Changed migrations: $CHANGED" echo "Changed migrations: $CHANGED"
echo "CHANGED_MIGRATIONS=$CHANGED" >> $GITHUB_ENV echo "CHANGED_MIGRATIONS=$CHANGED" >> $GITHUB_ENV
- name: Run migrations - name: Run changed migrations and verify schema
if: env.CHANGED_MIGRATIONS != '' if: env.CHANGED_MIGRATIONS != ''
run: | run: |
export PGPASSWORD="${DB_PASSWORD}" export PGPASSWORD="${DB_PASSWORD}"
@@ -55,18 +55,27 @@ jobs:
DB_USER: ${{ secrets.DB_USER }} DB_USER: ${{ secrets.DB_USER }}
DB_PASSWORD: ${{ secrets.DB_PASSWORD }} DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
- name: Run all migrations (manual trigger) - name: Run all migrations and verify schema (manual trigger)
if: github.event_name == 'workflow_dispatch' if: github.event_name == 'workflow_dispatch'
run: | run: |
export PGPASSWORD="${DB_PASSWORD}" export PGPASSWORD="${DB_PASSWORD}"
echo "=== Running all migrations in order ===" echo "=== Running all migrations in order ==="
FAILED=0
for f in $(ls crates/mem-store/migrations/*.sql | sort); do for f in $(ls crates/mem-store/migrations/*.sql | sort); do
echo "--- Applying: $f ---" echo "--- Applying: $f ---"
psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -f "$f" 2>&1 || true if ! psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -f "$f" 2>&1; then
echo "--- Done: $f ---" echo "ERROR: Migration $f failed!"
FAILED=1
else
echo "--- OK: $f ---"
fi
done done
if [ $FAILED -eq 1 ]; then
exit 1
fi
echo "=== Final schema ===" echo "=== Final schema ==="
psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -c "\dt memory*" psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -c "\dt memory*"
psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -c "\d memory_entity" psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -c "\d memory_entity"