Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/sdurutr436/stay-sidekick/llms.txt

Use this file to discover all available pages before exploring further.

Stay Sidekick uses six application-focused GitHub Actions workflows organized into CI validation, Docker image publishing, and security auditing. Every push to dev-herramientas or main triggers the full CI battery — lint, test, and build — across both the Python backend and the Node frontend/web stacks. Docker images are only pushed to Docker Hub when all three CI workflows have completed successfully on the exact same commit SHA, enforced by a dedicated verification job that queries the GitHub API before any build begins.

Workflows

The table below summarises all six workflows, their triggers, runtime environment, and primary action:
WorkflowTriggerStackAction
ci-python.ymlPush / PR to dev-herramientas, mainPython 3.12 + pytestruff check backend/app lint → pytest with postgres:16-alpine service container
ci-angular-tests.ymlPush / PR to dev-herramientas, mainNode 22 + VitestTests with Istanbul coverage threshold + production build verification
ci-angular.ymlPush / PR to dev-herramientas, mainNode 22 + Angular CLIProduction build of the Angular SPA
ci-web.ymlPush / PR to dev-herramientas, mainNode 22 + 11tyProduction build of the static public site
docker-publish.ymlAfter CI Angular, CI 11ty, and CI Python all pass on the same SHADocker + GitHub APIPublishes 4 images to Docker Hub with sha-<short>, main, and latest tags
trivy.ymlPR / push to main, weekly (Mon 04:23 UTC), manualTrivy + SARIFVulnerability and misconfiguration scan with HIGH/CRITICAL filter, results published to GitHub Security

CI workflow detail

ci-python.yml

Runs two sequential jobs:
  1. Lint — installs ruff and runs ruff check backend/app. The tests job has needs: lint and will not start if lint fails.
  2. Tests — spins up a postgres:16-alpine service container, installs requirements.txt plus pytest, then executes the full suite with --cov-fail-under=90. The HTML and XML coverage reports are uploaded as the backend-coverage artifact (14-day retention).
The service container is health-checked with pg_isready before tests start, ensuring a live PostgreSQL 16 connection is available throughout the run.

ci-angular-tests.yml

Runs two sequential jobs:
  1. test-frontend — installs dependencies with pnpm install --frozen-lockfile, then runs pnpm exec ng test --watch=false. The coverage report is uploaded as the coverage-report artifact (14-day retention).
  2. deploy-check (needs: test-frontend) — performs a full pnpm exec ng build --configuration production to confirm the production build compiles cleanly after tests pass.
The separation ensures a coverage failure blocks the build step, not the other way around.

ci-angular.yml

A single build job that installs frontend dependencies and runs pnpm run build. This is the fast build-only check that docker-publish.yml requires to pass before publishing the Angular image. It runs in parallel with ci-angular-tests.yml on every push.

ci-web.yml

A single build job that installs web/ dependencies and runs pnpm run build with TURNSTILE_SITE_KEY set to an empty string (safe for CI). This is the 11ty static site build check required by docker-publish.yml before the web image is built and pushed.

Conditional publishing

The docker-publish.yml workflow is triggered by workflow_run events — it fires each time any of the three CI workflows (CI Angular, CI 11ty, CI Python) completes on a dev-herramientas or main branch. However, it does not blindly publish on every trigger. Instead, a dedicated verificar job runs first and gates the entire publish pipeline.
1

verificar job — query the GitHub API

The verificar job uses the GitHub CLI (gh api) to look up the three required CI workflows by name and filter them to runs matching the exact head_sha of the triggering commit:
for WF in "CI Angular" "CI 11ty" "CI Python"; do
  CONCLUSION=$(gh api "repos/${{ github.repository }}/actions/runs" \
    --jq "[.workflow_runs[] | select(.name == \"$WF\" and .head_sha == \"$SHA\")][0].conclusion" \
    | tr -d '"')

  if [ "$CONCLUSION" = "success" ]; then
    echo "✅  $WF"
  else
    echo "⏳  $WF — ${CONCLUSION:-en progreso}"
    TODOS=false
  fi
done

echo "todos-pasaron=$TODOS" >> $GITHUB_OUTPUT
The result (true or false) is emitted as a job output named todos-pasaron.
2

publicar job — conditional on verificar output

The publicar job has needs: verificar and an if condition:
if: needs.verificar.outputs.todos-pasaron == 'true'
If any of the three CI workflows has not yet completed, or completed with a status other than success, TODOS is false and the publicar job is skipped entirely. No partial or speculative builds occur.
3

Build and push all four images

When the condition is met, the publicar job checks out the repository at the exact triggering SHA, extracts a 7-character short SHA, logs into Docker Hub using repository secrets, then builds and pushes all four images sequentially.
The verificar job fires every time any one of the three CI workflows completes. On most commits it will run three times — once per workflow completion — but only one of those runs will find all three in success state. The other two will silently skip the publicar job. This is expected behaviour and does not indicate a pipeline failure.

Docker Hub images

Four images are built and published to Docker Hub on every qualifying commit to main:
ImageSource directoryRole
sdurutr436/stay-sidekick-backend./backendFlask + Gunicorn API server
sdurutr436/stay-sidekick-frontend./frontendAngular SPA served by internal Nginx
sdurutr436/stay-sidekick-web./web (root context, web/Dockerfile)11ty static site served by internal Nginx
sdurutr436/stay-sidekick-nginx./nginxReverse proxy with security headers
Each image is tagged with three tags simultaneously:
TagFormatPurpose
Commit SHAsha-<7-char-short-sha>Immutable reference to an exact build
BranchmainLatest build on the main branch
ConveniencelatestStandard Docker Hub default tag
The web image receives the TURNSTILE_SITE_KEY build argument from the TURNSTILE_SITE_KEY repository secret, so the published image includes the production Cloudflare Turnstile site key baked into the static build.
Pull the latest published image locally with:
docker pull sdurutr436/stay-sidekick-backend:latest
To pull a specific commit build using its SHA tag:
docker pull sdurutr436/stay-sidekick-backend:sha-a1b2c3d
All four images are available at hub.docker.com/u/sdurutr436.

Branch strategy

All CI workflows (ci-python.yml, ci-angular-tests.yml, ci-angular.yml, ci-web.yml) trigger on pushes and pull requests targeting two branches:
BranchPurpose
dev-herramientasActive feature development branch — CI runs here to catch issues before merging
mainStable branch — CI runs here and, on pass, gates Docker image publishing
The Trivy security audit runs on pushes to main and on pull requests targeting main. The trivy.yml path filter restricts scans to runs that actually touch relevant files (backend/**, frontend/**, web/**, nginx/**, workflows, Docker Compose, package.json, railway.toml), avoiding unnecessary audit runs on documentation-only changes. The branch naming conventions for contributors (from CONTRIBUTING.md) are:
PrefixUse case
dev-*Normal feature work
fix-*Bug fixes
hotfix-*Urgent production issues

Build docs developers (and LLMs) love