diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index b3ad039..559d12e 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -9,24 +9,29 @@ on: pull_request: +permissions: + contents: read + +env: + IMAGE: snegov/seafile-client + jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Validate compose example run: docker compose --file compose.example.yaml config --quiet - - name: Run tests - run: | - if [ -f docker-compose.test.yml ]; then - docker-compose --file docker-compose.test.yml build - docker-compose --file docker-compose.test.yml run sut - else - docker build . --file Dockerfile - fi + - name: Build image + uses: docker/build-push-action@v6 + with: + context: . + push: false + load: true + tags: ${{ env.IMAGE }}:ci push: needs: test @@ -35,22 +40,30 @@ jobs: if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - - uses: docker/build-push-action@v1 + # Every tag of a release must resolve to one manifest digest, so the + # image is built once and all tags are attached to that single build. + - name: Collect tags and labels + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.IMAGE }} + tags: | + type=ref,event=tag + flavor: | + latest=true + + - name: Log in to Docker Hub + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - repository: snegov/seafile-client - tag_with_ref: true - add_git_labels: true - push: ${{ startsWith(github.ref, 'refs/tags/') }} + password: ${{ secrets.DOCKER_TOKEN }} - - uses: docker/build-push-action@v1 + - name: Build and push + uses: docker/build-push-action@v6 with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - repository: snegov/seafile-client - tags: latest - add_git_labels: true - push: ${{ startsWith(github.ref, 'refs/tags/') }} + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/IMPROVEMENTS.md b/IMPROVEMENTS.md index 960eaf0..7143150 100644 --- a/IMPROVEMENTS.md +++ b/IMPROVEMENTS.md @@ -147,12 +147,15 @@ Acceptance criteria: ### CI and release pipeline -- [ ] Replace `actions/checkout@v2` and `docker/build-push-action@v1`. -- [ ] Set workflow permissions explicitly to `contents: read` by default. -- [ ] Use a scoped Docker Hub access token. -- [ ] Build a release image once and attach all version and `latest` tags to +- [x] Replace `actions/checkout@v2` and `docker/build-push-action@v1`. +- [x] Set workflow permissions explicitly to `contents: read` by default. +- [x] Use a scoped Docker Hub access token. The workflow now reads + `secrets.DOCKER_TOKEN`; the repository secret still has to be created from a + scoped Docker Hub token before the next tag is pushed. +- [x] Build a release image once and attach all version and `latest` tags to the same manifest digest. -- [ ] Add OCI labels, an SBOM, provenance, and image signing. +- [x] Add OCI labels via `docker/metadata-action`. +- [ ] Add an SBOM, provenance, and image signing. - [ ] Add dependency updates for Python, Docker, and GitHub Actions. - [ ] Run dependency and image scans on pull requests and on a schedule.