diff --git a/.gitea/workflows/ci-cd.yml b/.gitea/workflows/ci-cd.yml index 89abc57d7..77a7e5b79 100755 --- a/.gitea/workflows/ci-cd.yml +++ b/.gitea/workflows/ci-cd.yml @@ -33,15 +33,12 @@ concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }} cancel-in-progress: true jobs: - validate: - name: Validate Code Quality And Tests + validate-code-quality: + name: Validate - Code Quality runs-on: - - ci-l2 + - ci-l1 - host - timeout-minutes: 20 - env: - DATABASE_URL: postgresql+psycopg://postgres:postgres@127.0.0.1:5432/xiaoxia_saas - USE_IN_MEMORY_DB: 'false' + timeout-minutes: 15 steps: - name: Checkout code shell: sh @@ -130,6 +127,79 @@ jobs: bash -n scripts/init_production_env.sh + ' + - name: Job duration summary + if: always() + shell: sh + run: "set +eu\nif [ -n \"$JOB_START_TIME\" ]; then\n END_TIME=$(date +%s)\n DURATION=$((END_TIME - JOB_START_TIME))\n MINS=$((DURATION / 60))\n SECS=$((DURATION % 60))\n echo \"JOB_DURATION_SECONDS=$DURATION\" >> $GITHUB_ENV\n echo \"=== Job Duration: ${MINS}m${SECS}s ===\"\nelse\n echo \"JOB_DURATION_SECONDS=0\" >> $GITHUB_ENV\n echo \"=== Job Duration: unknown ===\"\nfi\n" + - name: Notify on failure + continue-on-error: true + if: failure() + shell: sh + env: + CI_NOTIFY_WEBHOOK: ${{ secrets.CI_NOTIFY_WEBHOOK }} + run: 'set +e + + NOTIFY_MODE=failure JOB_NAME="Validate - Code Quality" python3 scripts/ci_notify.py + + ' + + validate-db-migrations: + name: Validate - DB Migrations + runs-on: + - ci-l2 + - host + timeout-minutes: 15 + env: + DATABASE_URL: postgresql+psycopg://postgres:postgres@127.0.0.1:5432/xiaoxia_saas + USE_IN_MEMORY_DB: 'false' + steps: + - name: Checkout code + shell: sh + env: + GITHUB_TOKEN: ${{ github.token }} + run: "set -eu\npython3 - <<'PY'\nimport io, os, tarfile, time, urllib.request, urllib.error\nurl = f\"{os.environ['GITHUB_API_URL']}/repos/{os.environ['GITHUB_REPOSITORY']}/archive/{os.environ['GITHUB_SHA']}.tar.gz\"\nrequest = urllib.request.Request(url, headers={\"Authorization\": f\"token {os.environ['GITHUB_TOKEN']}\"})\nlast_err = None\nfor attempt in range(5):\n try:\n with urllib.request.urlopen(request, timeout=120) as response:\n archive = response.read()\n break\n except urllib.error.HTTPError as e:\n last_err = e\n if e.code >= 500 and attempt < 4:\n wait = 2 ** attempt\n print(f\"Checkout HTTP {e.code}, retrying in {wait}s (attempt {attempt+1}/5)...\")\n time.sleep(wait)\n continue\n raise\n except Exception as e:\n last_err = e\n if attempt < 4:\n wait = 2 ** attempt\n print(f\"Checkout error: {e}, retrying in {wait}s (attempt {attempt+1}/5)...\"\ + )\n time.sleep(wait)\n continue\n raise\nelse:\n raise last_err\nwith tarfile.open(fileobj=io.BytesIO(archive), mode='r:gz') as tar:\n root_prefix = tar.getmembers()[0].name.split('/', 1)[0] + '/'\n for member in tar.getmembers():\n name = member.name\n if name == root_prefix[:-1]:\n continue\n if name.startswith(root_prefix):\n member.name = name[len(root_prefix):]\n if member.name:\n tar.extract(member, '.')\nPY\n" + - name: Record job start time + shell: sh + run: 'set -eu + + echo "JOB_START_TIME=$(date +%s)" >> $GITHUB_ENV + + echo "Job started at $(date)" + + ' + - name: Verify CI environment + shell: sh + run: 'set -eu + + python3 --version + + python3 -m pip --version + + echo "CI environment is ready" + + ' + - name: Install dependencies + shell: sh + run: 'set -eu + + python3 -m pip install -q -r requirements-base.txt + + python3 -m pip install -q -r requirements.txt + + python3 -m pip install -q -r requirements-dev.txt + + python3 -m black --version + + python3 -m isort --version-number + + python3 -m ruff --version + + bandit --version + + pytest --version + ' - name: Start PostgreSQL for validate (isolated container) shell: sh @@ -162,9 +232,30 @@ jobs: CI_NOTIFY_WEBHOOK: ${{ secrets.CI_NOTIFY_WEBHOOK }} run: 'set +e - NOTIFY_MODE=failure JOB_NAME="Validate Code Quality And Tests" python3 scripts/ci_notify.py + NOTIFY_MODE=failure JOB_NAME="Validate - Code Quality" python3 scripts/ci_notify.py ' + + validate: + name: Validate Code Quality And Tests + needs: [validate-code-quality, validate-db-migrations] + runs-on: + - ci-l1 + - host + timeout-minutes: 2 + steps: + - name: Validate summary + shell: sh + run: 'set -eu + + echo "All validate checks passed ✅" + + echo " - Code Quality: PASSED" + + echo " - DB Migrations: PASSED" + + ' + unit-tests: name: Unit Tests runs-on: