App CI (Stage 3)
This repo uses GitHub Actions to ensure every PR is validated and every merge to
main produces a deployable artifact.
Goals (Stage 3)
- PRs: fail fast on docs + workflow mistakes, and prove the app still boots.
- main: publish a container image to GHCR.
Workflows involved
.github/workflows/ci.yml- Lints GitHub Actions workflows (actionlint)
- Docs quality checks (markdownlint + lychee)
-
PR-only: build container + smoke test via Docker Compose
-
.github/workflows/publish-image.yml - Builds the app image
- Pushes to GHCR on
main
What runs on pull requests
1) Workflow lint: actionlint
Purpose: catch invalid inputs, typos, wrong action parameters, invalid contexts, and similar mistakes before merge.
Where: ci.yml job actionlint
Expected outcome:
- Workflow YAML is valid
- Incorrect action inputs are rejected (for example, passing
contexttodocker/setup-buildx-action, which does not support it)
2) Docs quality gates
Where: ci.yml job docs-quality
- Markdown lint (format consistency)
- Link check (keeps repo clean)
3) App container: build + smoke test
Where: ci.yml job app-container-pr
Steps:
- Build the app image with Buildx (
docker/build-push-action) and load it into the runner Docker daemon. - Start the Compose stack from
projects/app/. - Validate the HTTP health endpoint.
Smoke test commands (conceptually):
docker compose up -d --waitdocker compose pscurl http://localhost:8000/healthz
Notes:
- The curl check can fail if the app container is still starting even though Compose has started the container. The job should rely on service health and /or retry the curl check briefly.
What runs on push to main
Publish container image to GHCR
Where: publish-image.yml
Image name:
ghcr.io/<owner>/<repo>/app
Tags:
latestsha-<git-sha>(orshatag style produced by metadata-action)
Authentication:
- Uses
GITHUB_TOKENwithpackages: write
Artifacts produced
- GHCR container image:
ghcr.io/viprapp/jevops/app:latestghcr.io/viprapp/jevops/app:sha-...
How to verify quickly
Check CI on a PR
- Open the PR
- Ensure these checks pass:
- actionlint
- docs-quality
- app - build + smoke test (PR)
Check publish on main
- Merge PR to
main - Confirm
publish-imageworkflow run succeeded - Confirm tags exist in GHCR for the repo
Common issues and how we catch them
- Wrong paths (for example wrong Dockerfile path):
- Caught by actionlint (workflow validation) and by the container build step
- Wrong action inputs:
- Caught by actionlint (example: invalid inputs to setup-buildx-action)
- Compose starts but app not ready yet (curl reset/refused):
- Fix by waiting for health or adding small curl retry loop