ci: run the real suites before publishing images

The pipeline ran py_compile plus four unit tests, then built and called the
Portainer webhook. None of that starts the application, so a missing import in
local/auth.py passed every check and reached production, where it returned 500
on every session, login and registration.

Add an integration job that builds the localhost stack and runs the suites that
already existed but were never executed automatically: smoke, workflow,
security, scanning, retention, runtime security, and the two browser tests.
publish-and-deploy now depends on it, so a failure blocks the deploy instead of
shipping.

Verified by reintroducing the original defect: py_compile and the unit tests
still passed, and smoke_test failed on /session, which would have stopped the
release.

The browser tests need a real Chrome and are skipped with a warning when the
runner has none; installing google-chrome-stable or setting CHROME_BIN makes
them gate too. Every other suite gates unconditionally.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Cauê Faleiros
2026-09-18 18:55:07 -03:00
parent 52ae13c9a1
commit 5d669cbcce

View File

@@ -24,9 +24,77 @@ jobs:
local.test_pricing -v
sh -n local/lock_dependencies.sh
integration:
name: Integration suite on a real stack
needs: validate
runs-on: ubuntu-latest
timeout-minutes: 45
env:
SITE_PORT: "8080"
KANBAN_PORT: "8081"
API_PORT: "8000"
COMPOSE: docker compose -f compose.local.yaml
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
# py_compile cannot see an unresolved name, and the four unit tests above
# never start the application. A missing import in local/auth.py therefore
# reached production and returned 500 on every session, login and
# registration. These suites exercise the running stack and would have
# failed on it immediately.
- name: Start the stack
run: |
$COMPOSE up --build -d --wait --wait-timeout 600
$COMPOSE ps
- name: API and workflow regressions
run: |
python3 -m local.smoke_test
python3 -m local.workflow_test
python3 -m local.security_test
python3 -m local.scanning_test
- name: Runtime and retention regressions
run: |
$COMPOSE exec -T api python -m local.retention_test
$COMPOSE exec -T api python -m local.runtime_security_test
# These need a real Chrome. They are the only coverage for the artwork
# editor and the full customer journey, so install google-chrome-stable
# (or set CHROME_BIN) on the runner to make them gate deployments. The
# suites above stay hard gates either way.
- name: Browser regressions
run: |
for candidate in "$CHROME_BIN" /usr/bin/google-chrome-stable \
/usr/bin/google-chrome /usr/bin/chromium /usr/bin/chromium-browser; do
if [ -n "$candidate" ] && [ -x "$candidate" ]; then
export CHROME_BIN="$candidate"
break
fi
done
if [ ! -x "${CHROME_BIN:-}" ]; then
echo "::warning::No Chrome on this runner; browser regressions were NOT run."
echo "Install google-chrome-stable or set CHROME_BIN to gate on them."
exit 0
fi
echo "Using $CHROME_BIN"
node local/artwork_browser_test.mjs
node local/browser_test.mjs
- name: Diagnostics on failure
if: failure()
run: |
$COMPOSE ps || true
$COMPOSE logs --tail 200 api worker site kanban || true
- name: Tear down
if: always()
run: $COMPOSE down -v || true
publish-and-deploy:
name: Publish images and notify Portainer
needs: validate
needs: [validate, integration]
if: gitea.event_name == 'push' && gitea.ref == 'refs/heads/main'
runs-on: ubuntu-latest
timeout-minutes: 45