BM: Baca dalam Bahasa Melayu
World C2: Container Pipelines · Boss challenge
Green line
You will learn: to make every PR build, test and scan, and every merge ship a tagged image.
Checked with GitHub Actions 2026-10 on 31 Oct 2026
The problem
Pick an event. Press Run and watch the line.
A pull request from a fork runs the line. The build tries to push to ghcr.io and is denied.
Workflow file .github/workflows/green-line.yml
name: Green line on: push: branches: [main] pull_request: permissions: contents: read packages: write jobs: image: runs-on: ubuntu-latest steps: - uses: docker/setup-buildx-action@v4 - uses: docker/login-action@v4 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - uses: docker/build-push-action@v7 with: push: true tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
The line
Pull request from a fork · stranger:feature → main
Boss: the green line! Mei sends her first PR from a fork. The line turns red. Press Run and read the red line.
Check
Plain words: a PR tried to push, with a read-only key. Should a PR push an image at all?
Pick one answer.
Try it
Room 1: fix the yellow line. PRs should only build. Main should push.
The line is red. Fix the yellow lines, then run again.
Workflow file .github/workflows/green-line.yml
name: Green line on: push: branches: [main] pull_request: permissions: contents: read packages: write jobs: image: runs-on: ubuntu-latest steps: - uses: docker/setup-buildx-action@v4 - uses: docker/login-action@v4 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - uses: docker/build-push-action@v7 with: push: true tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
Yellow: lines 21–21. You can change these.
The line
Pull request from a fork · stranger:feature → main
Hint
The event name for a PR is pull_request. Push when it is anything else.Check
Room 2: what happens where on the green line?
Drag a card into a box. Or tap the card, then tap the box.
Try it
Room 3: the API tests need Postgres, and they can’t find it. Give the job a database.
The line is red. Fix the yellow lines, then run again.
Workflow file .github/workflows/test.yml
name: Test on: pull_request: permissions: contents: read jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 - uses: actions/setup-node@v7 with: node-version: 24 - run: npm ci - run: npm test env: DATABASE_URL: postgres://postgres:test@localhost:5432/postgres
Yellow: lines 8–8. You can change these.
The line
Pull request · feature → main
Hint
Read the red line: which port does nobody answer on?Check
Room 4: a PR’s image has a CRITICAL CVE. What should the line do?
Pick one answer.
Predict
Final room: the whole line, with a CRITICAL CVE in the image. Tap the station that will stop it, then press Run.
Which station will stop the line? Tap it, then press Run.
Workflow file .github/workflows/green-line.yml
name: Green line on: push: branches: [main] pull_request: permissions: contents: read jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 - run: docker compose up -d --wait - run: docker compose run --rm api npm test image: needs: test runs-on: ubuntu-latest permissions: contents: read packages: write steps: - uses: docker/setup-buildx-action@v4 - id: meta uses: docker/metadata-action@v6 with: images: ghcr.io/${{ github.repository }} - uses: docker/build-push-action@v7 with: load: true tags: kedai-kancil:scan cache-from: type=gha cache-to: type=gha,mode=max - uses: aquasecurity/trivy-action@v0.36.0 with: image-ref: kedai-kancil:scan severity: CRITICAL exit-code: '1' - if: github.event_name != 'pull_request' uses: docker/login-action@v4 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - uses: docker/build-push-action@v7 with: push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha
The line
Pull request · feature → main
Hint
The tests pass. Which job scans the image?You did it!
You can now check every PR and ship every merge.
Go deeper (optional)
Here is the whole green line. Compose runs the tests. Then the image is built and scanned. Only main logs in and pushes. The scan comes before the push, so a bad pack never ships. Mission 2 puts this line in your own repo.
Pick an event. Press Run and watch the line.
The whole green line. On a PR: tests, build, scan, no push. On main: the same, plus login and push.
Workflow file .github/workflows/green-line.yml
name: Green line on: push: branches: [main] pull_request: permissions: contents: read jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 - run: docker compose up -d --wait - run: docker compose run --rm api npm test image: needs: test runs-on: ubuntu-latest permissions: contents: read packages: write steps: - uses: docker/setup-buildx-action@v4 - id: meta uses: docker/metadata-action@v6 with: images: ghcr.io/${{ github.repository }} - uses: docker/build-push-action@v7 with: load: true tags: kedai-kancil:scan cache-from: type=gha cache-to: type=gha,mode=max - uses: aquasecurity/trivy-action@v0.36.0 with: image-ref: kedai-kancil:scan severity: CRITICAL exit-code: '1' - if: github.event_name != 'pull_request' uses: docker/login-action@v4 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - uses: docker/build-push-action@v7 with: push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha
The line
Pull request · feature → main
Bahasa Melayu
Bos: talian hijau! Mei hantar PR pertamanya dari fork. Talian jadi merah. Tekan Run dan baca baris merah.
Maksudnya: satu PR cuba push, dengan kunci baca sahaja. Patutkah PR push image langsung?
Bilik 1: baiki baris kuning. PR patut bina sahaja. Main patut push.
Bilik 2: apa berlaku di mana pada talian hijau?
Bilik 3: ujian API perlukan Postgres, dan ia tak jumpa. Beri job ini pangkalan data.
Bilik 4: image sebuah PR ada CVE CRITICAL. Apa patut talian buat?
Bilik akhir: seluruh talian, dengan CVE CRITICAL dalam image. Ketik stesen yang akan hentikannya, kemudian tekan Run.
Kini anda boleh semak setiap PR dan hantar setiap merge.
You finished this before. Practice is always welcome!
Official docs: Docker docs: GitHub Actions · Publishing Docker images · About service containers
You've learned for 25 minutes. A short break helps your brain.
Sprint done! Great focus. Stretch for a minute?