From f4d2c3049302be631db581549c3e9ddffdb94c6d Mon Sep 17 00:00:00 2001 From: odweta Date: Thu, 10 Sep 2026 16:05:06 +0200 Subject: [PATCH] Add CI/CD GitHub Actions workflow for dev image builds - Run tests on push/PR to main - Build and push Docker image to GHCR as :dev and :dev- on push to main - Document image pull/run instructions in README Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/workflows/ci-cd.yml | 85 +++++++++++++++++++++++++++++++++++++ README.md | 30 ++++++++++++- 2 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/ci-cd.yml diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml new file mode 100644 index 0000000..8b827bc --- /dev/null +++ b/.github/workflows/ci-cd.yml @@ -0,0 +1,85 @@ +name: CI/CD + +on: + push: + branches: [main] + pull_request: + branches: [main] + workflow_dispatch: + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + test: + name: Test + runs-on: ubuntu-latest + defaults: + run: + working-directory: app + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '22' + cache: 'npm' + cache-dependency-path: app/package-lock.json + + - name: Install dependencies + run: npm ci + + - name: Run tests + run: npm test + + build-and-push: + name: Build and push image (dev) + needs: test + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract image metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=raw,value=dev + type=sha,prefix=dev- + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and push + uses: docker/build-push-action@v6 + with: + context: ./app + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Summary + run: | + echo "### Dev image published :rocket:" >> "$GITHUB_STEP_SUMMARY" + echo "" >> "$GITHUB_STEP_SUMMARY" + echo '```' >> "$GITHUB_STEP_SUMMARY" + echo "${{ steps.meta.outputs.tags }}" >> "$GITHUB_STEP_SUMMARY" + echo '```' >> "$GITHUB_STEP_SUMMARY" diff --git a/README.md b/README.md index 402dc56..d31ecd9 100644 --- a/README.md +++ b/README.md @@ -19,4 +19,32 @@ docker compose up --build Then open `http://localhost:3001` and create an account. PostgreSQL data is kept in the `postgres-data` Docker volume, so it survives app and container restarts. -To remove the database as well, run `docker compose down -v`. \ No newline at end of file +To remove the database as well, run `docker compose down -v`. + +## CI/CD + +On every push to `main`, GitHub Actions (`.github/workflows/ci-cd.yml`) runs the +test suite, then builds and publishes a dev image to the GitHub Container +Registry: + +``` +ghcr.io/odweta/fakturovac:dev +``` + +A commit-pinned tag (`ghcr.io/odweta/fakturovac:dev-`) is published +alongside `:dev` for traceability. Pull requests only run the test job. + +To pull and run the latest dev image in a testing environment: + +```bash +docker login ghcr.io -u # only needed if the package is private +docker pull ghcr.io/odweta/fakturovac:dev +docker run -d -p 3001:3001 \ + -e DATABASE_URL=postgres://fakturovac:fakturovac@:5432/fakturovac \ + -e NODE_ENV=production \ + ghcr.io/odweta/fakturovac:dev +``` + +The package's visibility (public/private) is managed under the repository's +**Packages** settings on GitHub; no extra secrets are required since the +workflow authenticates with the built-in `GITHUB_TOKEN`. \ No newline at end of file