diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 0868784..5e9c741 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -3,8 +3,9 @@ name: Publish image to GHCR on: workflow_dispatch: push: - branches: - - main + tags: + - "[0-9]+.[0-9]+.[0-9]+" + - "[0-9]+.[0-9]+.[0-9]+-rc.?[0-9]+" defaults: run: @@ -19,35 +20,38 @@ jobs: uses: actions/checkout@v6 - name: Docker Login to GitHub Container Registry - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@v4 - name: Set up Docker Buildx id: buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 - - name: Cache Parameters - id: cache_params - run: | - CACHE_SCOPE="cal-itp" - MAIN_BRANCH_REF="refs/heads/main" - - echo "cache_from_args=type=gha,scope=${CACHE_SCOPE},ref=${MAIN_BRANCH_REF}" >> $GITHUB_OUTPUT - echo "cache_to_args=type=gha,scope=${CACHE_SCOPE},mode=max,ref=${MAIN_BRANCH_REF}" >> $GITHUB_OUTPUT + - name: Extract metadata + id: meta + uses: docker/metadata-action@v6 + with: + images: ${{ env.IMAGE_NAME }} + # https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry#labelling-container-images + labels: | + org.opencontainers.image.source=https://github.com/${{ github.repository }} + org.opencontainers.image.description="A base Docker image for Cal-ITP Python web applications" + org.opencontainers.image.licenses="Apache-2.0" - name: Build, tag, and push image to GitHub Container Registry - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: builder: ${{ steps.buildx.outputs.name }} build-args: GIT-SHA=${{ github.sha }} - cache-from: ${{ steps.cache_params.outputs.cache_from_args }} - cache-to: ${{ steps.cache_params.outputs.cache_to_args }} + # https://docs.docker.com/build/ci/github-actions/cache/#github-cache + cache-from: type=gha + cache-to: type=gha,mode=max context: . platforms: linux/amd64,linux/arm64 file: appcontainer/Dockerfile @@ -55,3 +59,24 @@ jobs: tags: | ghcr.io/${{ github.repository }}:${{ github.ref_name }} ghcr.io/${{ github.repository }}:${{ github.sha }} + annotations: ${{ steps.meta.outputs.annotations }} + + release: + needs: publish + if: ${{ !contains(github.ref_name, '-rc') }} + runs-on: ubuntu-latest + permissions: + # https://github.com/softprops/action-gh-release#permissions + contents: write + + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Release + uses: softprops/action-gh-release@v2 + with: + prerelease: false + generate_release_notes: true diff --git a/README.md b/README.md index 801f921..5b21e53 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,10 @@ A base [Docker image](https://www.docker.com/) for Cal-ITP Python web applicatio ## Usage -Reference one of the `image:tag` from GitHub Container Registry in a `Dockerfile`. E.g. for the `main` branch: +Reference an `image:tag` from GitHub Container Registry in a `Dockerfile`. E.g. for the `1.0.0` release: ```dockerfile -FROM ghcr.io/cal-itp/docker-python-web:main +FROM ghcr.io/cal-itp/docker-python-web:1.0.0 COPY my_app my_app @@ -34,7 +34,7 @@ CMD "nginx && python -m gunicorn -c $GUNICORN_CONF my_app.wsgi" Or from the command line: ```shell -docker pull ghcr.io/cal-itp/docker-python-web:main +docker pull ghcr.io/cal-itp/docker-python-web:1.0.0 ``` ## Development diff --git a/docs/guides/publish-an-image.md b/docs/guides/publish-an-image.md new file mode 100644 index 0000000..6a8866f --- /dev/null +++ b/docs/guides/publish-an-image.md @@ -0,0 +1,22 @@ +# Publish an image + +Historically, a new image was published each time a commit was pushed to `main`. Now we use [tag-based deployment](https://github.com/cal-itp/docker-python-web/issues/73). + +The steps to release are nearly identical to [benefits](https://docs.calitp.org/benefits/guides/release/), with the exception that we use a [SemVer](https://semver.org/) numbering scheme. + +## 0. Decide on the new version number + +Given a version number `MAJOR.MINOR.PATCH`, increment the: + +- MAJOR version when you make incompatible API changes +- MINOR version when you add functionality in a backward compatible manner +- PATCH version when you make backward compatible bug fixes + +Images are published to the GitHub Container Registry when a tag is pushed with a version number similar to either of the following: + +```bash +# genuine release +1.2.3 +# release candidate +2.3.4-rc.1 +```