From 3646521a75600bdd0ae3a888e54a0677fbf59146 Mon Sep 17 00:00:00 2001 From: DevOps Date: Tue, 9 Jun 2026 21:03:03 +0200 Subject: [PATCH] fix(ci): version bump from git tags + .env from secrets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 1 — Deploy reliability: - Version bump: derive current version from 'git describe --tags' instead of VERSION file. This eliminates race conditions where the VERSION file is stale but the tag already exists from a previous failed run. - Tag creation: use 'git tag -f' + 'git push --force --tags' to handle retries gracefully when tags already exist. - Environment: provision .env at the host deploy path from Gitea secrets (ENV_POSTGRES_PASSWORD, ENV_JWT_KEY, ENV_OWNER_PASSWORD, ENV_OPENCLAW_TOKEN). This ensures .env always exists on the host even though it's excluded from the sync step for security. Runner label was already fixed in previous commit (runs-on: ubuntu-latest). --- .gitea/workflows/deploy.yaml | 71 ++++++++++++++++++++++++++++++------ 1 file changed, 60 insertions(+), 11 deletions(-) diff --git a/.gitea/workflows/deploy.yaml b/.gitea/workflows/deploy.yaml index 8374ce8..5734164 100644 --- a/.gitea/workflows/deploy.yaml +++ b/.gitea/workflows/deploy.yaml @@ -1,6 +1,12 @@ name: Deploy to Production run-name: 🚀 Deploy ${{ inputs.bump_version || 'patch' }} by @${{ gitea.actor }} +# ─────────────────────────────────────────────────── +# Trigger: automatic after CI success, or manual dispatch. +# Runner: uses ubuntu-latest label (consistently present on +# runner id=5: linux,dotnet,node,deploy,ubuntu-latest,…). +# Standard labels avoid custom-label matching edge cases. +# ─────────────────────────────────────────────────── on: workflow_run: workflows: ["CI - Build & Test"] @@ -34,20 +40,29 @@ jobs: runs-on: ubuntu-latest if: ${{ gitea.event_name != 'workflow_run' || gitea.event.workflow_run.conclusion == 'success' }} steps: + # ── Step 1: Checkout ───────────────────── - name: Checkout latest code uses: actions/checkout@v4 with: fetch-depth: 0 fetch-tags: true + # ── Step 2: Version bump (race-free) ───── + # Derives current version from git tags (not VERSION file) to + # avoid race conditions where tag exists but VERSION is stale. + # Uses --force on tag+push to handle retries after failed runs. - name: Version Bump run: | - CURRENT_VERSION=$(cat VERSION) - echo "📦 Current version: $CURRENT_VERSION" + set -euo pipefail - MAJOR=$(echo $CURRENT_VERSION | cut -d. -f1) - MINOR=$(echo $CURRENT_VERSION | cut -d. -f2) - PATCH=$(echo $CURRENT_VERSION | cut -d. -f3) + # Source of truth: latest git tag + TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") + CURRENT_VERSION="${TAG#v}" + echo "📦 Current version (from git tags): $CURRENT_VERSION" + + MAJOR=$(echo "$CURRENT_VERSION" | cut -d. -f1) + MINOR=$(echo "$CURRENT_VERSION" | cut -d. -f2) + PATCH=$(echo "$CURRENT_VERSION" | cut -d. -f3) case "${{ inputs.bump_version }}" in major) @@ -66,10 +81,40 @@ jobs: git config user.name "DevOps" git add VERSION git commit -m "chore: bump version to v${NEW_VERSION} [skip ci]" - git tag "v${NEW_VERSION}" - git push "https://devops:${{ secrets.GIT_TOKEN }}@git.noveria.net/bao/nexus.git" HEAD:main --tags + + # --force avoids "tag already exists" when re-running after a failed attempt + git tag -f "v${NEW_VERSION}" + git push "https://devops:${{ secrets.GIT_TOKEN }}@git.noveria.net/bao/nexus.git" HEAD:main --force --tags echo "✅ Version bumped to v${NEW_VERSION}" + # ── Step 3: Provision .env on host ──────── + # The sync step excludes .env for security, so we re-create it + # from Gitea secrets at the host deploy path BEFORE syncing code. + - name: Create .env on host + run: | + cat > /opt/openclaw/data/openclaw/workspace/nexus/.env << 'ENVEOF' + # Nexus Production Environment — auto-generated by CD pipeline + # Managed via Gitea secrets → do not edit manually on the host + + POSTGRES_DB=nexus + POSTGRES_USER=nexus + POSTGRES_PASSWORD=${{ secrets.ENV_POSTGRES_PASSWORD }} + + JWT_KEY=${{ secrets.ENV_JWT_KEY }} + JWT_ISSUER=nexus + JWT_AUDIENCE=nexus-web + + OWNER_EMAIL=vmbao62@hotmail.de + OWNER_PASSWORD=${{ secrets.ENV_OWNER_PASSWORD }} + OWNER_DISPLAY_NAME= + + OPENCLAW_BASE_URL=http://host.docker.internal:18789 + OPENCLAW_GATEWAY_TOKEN=${{ secrets.ENV_OPENCLAW_TOKEN }} + OPENCLAW_GATEWAY_PASSWORD= + ENVEOF + echo "✅ .env created at host deploy path" + + # ── Step 4: Sync code to host ───────────── - name: Sync code to host deploy path run: | docker run --rm \ @@ -84,9 +129,11 @@ jobs: -exec cp -a {} /dest/ \; " + # ── Step 5: Docker Buildx ───────────────── - name: Set up Docker Buildx run: docker buildx create --use 2>/dev/null || true + # ── Step 6: Build & Deploy ──────────────── - name: Build & Deploy run: | BUILD_ARGS="" @@ -101,17 +148,18 @@ jobs: docker:cli \ sh -c " set -e - if [ -n '${{ inputs.service }}' ]; then - echo '🚀 Deploying service: ${{ inputs.service }}' - docker compose build $BUILD_ARGS \${{ inputs.service }} + if [ -n '\${{ inputs.service }}' ]; then + echo '🚀 Deploying service: \${{ inputs.service }}' + docker compose build \$BUILD_ARGS \${{ inputs.service }} docker compose up -d --force-recreate \${{ inputs.service }} else echo '🚀 Deploying all services' - docker compose build $BUILD_ARGS + docker compose build \$BUILD_ARGS docker compose up -d --force-recreate fi " + # ── Step 7: Health Check ────────────────── - name: Health Check run: | sleep 5 @@ -126,6 +174,7 @@ jobs: sleep 5 done + # ── Step 8: Smoke test ──────────────────── - name: Verify (smoke test) run: | echo "🔍 Smoke test..."