4.5CI: building and pushing an image on every commit
The essentials in 30 seconds
- CI is the only image factory: on each push to main, it fetches the code, logs in to the registry and builds + pushes — no more “hand-built on the laptop” builds.
- Tag SHA + version: the commit fingerprint for exact traceability, the version for readability — production deploys the SHA or the version, never a moving alias.
- Idir's reflex: cache enabled for fast builds, credentials in repository secrets, never in the workflow file.
Threaded mini-case — Idir plugs in his team's image factory
Idir, junior DevOps in Algiers, is tired of hand-built images whose content nobody knows: he writes a workflow that, on each push to main, logs in to GHCR via the repository token, builds with cache and pushes the image tagged with the commit fingerprint. The team then pulls the image of the exact commit. Last milestone of the thread: each commit yields a deployable, traceable image, with no manual intervention.
Last case of thread 4.1-4.5 — Idir completes his level: publish, harden, expose, back up, automate.
1. The minimal pipeline that changes everything
On each push to main: fetch the code, log in to the registry (repository secret), build + push tagged. No more “hand-built on the laptop” builds: the CI is the only factory for images — like Idir's factory, each image has a known origin.
And only ship green: a test job before the build avoids pushing broken images.
2. Tagging smartly in CI
Push the commit fingerprint (exact traceability: this image = this code) + the version (readable, on git tag) + a branch alias in development. In production deploy the fingerprint or the version, never a moving alias — Idir can thus redeploy exactly the validated commit.
Pushing only the moving alias means becoming untraceable again: the pipeline must always produce at least one exact tag.
3. Cache and secrets: the two settings
Cache reuses layers between runs and divides build times. Credentials live in repository secrets, never in the workflow file. A pipeline showing a secret in logs is a pipeline to fix urgently — then revoke the exposed secret.
Minimum permission: the job only gets the rights it needs (package writes, nothing more).
🔎 Concrete example — 🔎 Concrete example — Minimal GitHub Actions workflow
Idir's factory: login via repository token, build + push of the fingerprint.
name: image
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
permissions:
packages: write
steps:
- uses: actions/checkout@v4
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v6
with:
push: true
tags: ghcr.io/monequipe/app:${{ github.sha }}
Reading: login via automatic token, build + push of the commit fingerprint.
Lesson: each commit yields a deployable, traceable image.
Section vocabulary
- Pipeline
- The automatic CHAIN: test, then build, then push (then deploy).
Simple example: On each push, Idir's factory tests, builds and pushes with no intervention.
What it is not: commands typed by hand on a laptop.
Reflex: repeating a build by hand: write it as a pipeline.
- SHA
- The commit FINGERPRINT: exact-traceability tag (this image = this code).
Simple example: Idir redeploys exactly the image of the validated commit.
What it is not: a moving alias changing content.
Reflex: production: deploy a fingerprint or a version, never an alias.
- CI secret
- SENSITIVE variable stored in the repository, masked from logs and never written in the file.
Simple example: Idir's registry token lives as a secret, not in the workflow.
What it is not: a password pasted in plain text in the file.
Reflex: credentials in CI: repository secret, always.
- Single factory
- CI ALONE produces deployed images: known origin, reproducible builds.
Simple example: Idir's team only deploys images coming out of the pipeline.
What it is not: images pushed “quickly” from a laptop.
Reflex: image of unknown origin: forbid, go through CI.
In practice — In practice — Your first factory
- Create the above workflow in .github/workflows/image.yml.
- Push to main and follow the run (green?).
- Check the tagged image in the registry packages.
- Pull it and run it: the commit runs.
Ready-to-say script — announcing the factory to the team (30 s)
“This is Idir: on each push to main, the CI tests, builds with cache and pushes the image tagged with the commit fingerprint. The token stays as a repository secret, never in the file. We deploy the exact fingerprint: no more images whose content nobody knows.”
Say in review: show the green run and the commit's image in the registry.
Copy-paste template — build + push workflow (generic, valid)
name: image
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
steps:
- uses: actions/checkout@v4
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ghcr.io/monequipe/app:${{ github.sha }}
Readable version on top
Like Idir: commit fingerprint + version on git tag — exact traceability and human reading.
Builds too slow
Enable cache between runs: unchanged layers are reused, builds are divided.
Broken image pushed
Add the test job before the build: only ship green.
Secret shown in log
Fix urgently, remove any debug output, then revoke and replace the exposed secret.
✓ Best practices
- Systematic exact tag + version on git tag.
- Enable build cache.
- Secrets in repository secrets, never in plain text.
✗ Common pitfalls
- Building locally then pushing “quickly”.
- Pushing only the moving alias (untraceable).
- Showing a secret in debug echo.
Key takeaways
- CI builds + pushes, not the laptop.
- Fingerprint = traceability, version = readability.
- Cache = fast builds.
- Secrets out of workflow, always.
48h challenge — apply tomorrow
On a real repository: create the workflow, push to main, check the tagged image in the registry then run it.
- I can write a build + push workflow triggered on main.
- I can tag fingerprint + version and deploy the exact.
- I can manage secrets, cache and minimal permissions.
Frequently asked questions
Should you test before building?
Yes: a test job before the build avoids pushing broken images. Only ship green.
And auto-deployment?
Next step: first a reliable factory (traceable build + push), then delivery. Without a reliable factory, automating deployment only accelerates mistakes.
In CI, which tag do you deploy to production?