From 2dfe694a011b7fa9d80c8e9a124943001e33f7ba Mon Sep 17 00:00:00 2001 From: owenlittlejohns Date: Wed, 11 Oct 2023 16:38:35 -0600 Subject: [PATCH] DAS-1937 - Add GitHub workflows for unit tests and Docker image publication. --- .github/workflows/publish_docker_image.yml | 83 +++++++++++++++++++ .github/workflows/run_tests.yml | 42 ++++++++++ .../workflows/run_tests_on_pull_requests.yml | 13 +++ README.md | 31 ++++++- bin/extract-release-notes.sh | 22 +++++ 5 files changed, 189 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/publish_docker_image.yml create mode 100644 .github/workflows/run_tests.yml create mode 100644 .github/workflows/run_tests_on_pull_requests.yml create mode 100755 bin/extract-release-notes.sh diff --git a/.github/workflows/publish_docker_image.yml b/.github/workflows/publish_docker_image.yml new file mode 100644 index 0000000..534c3bb --- /dev/null +++ b/.github/workflows/publish_docker_image.yml @@ -0,0 +1,83 @@ +# This workflow will run when changes are detected in the `main` branch, which +# must include an update to the `docker/service_version.txt` file. The workflow +# can also be manually triggered by a repository maintainer. This workflow will +# first trigger the reusable workflow in `.github/workflows/run_tests.yml`, +# which runs the `unittest` suite. If that workflow is successful, the latest +# version of the service Docker image is pushed to ghcr.io, a tag is added to +# the latest git commit, and a GitHub release is created with the release notes +# from the latest version of HOSS. +name: Publish Harmony OPeNDAP SubSetter (HOSS) Docker image + +on: + push: + branches: [ main ] + paths: docker/service_version.txt + workflow_dispatch: + +env: + IMAGE_NAME: ${{ github.repository }} + REGISTRY: ghcr.io + +jobs: + run_tests: + uses: ./.github/workflows/run_tests.yml + + build_and_publish_image: + needs: run_tests + runs-on: ubuntu-latest + environment: release + permissions: + # write permission is required to create a GitHub release + contents: write + id-token: write + packages: write + strategy: + fail-fast: false + + steps: + - name: Checkout harmony-opendap-subsetter repository + uses: actions/checkout@v3 + with: + lfs: true + + - name: Extract semantic version number + run: echo "semantic_version=$(cat docker/service_version.txt)" >> $GITHUB_ENV + + - name: Extract release version notes + run: | + version_release_notes=$(./bin/extract-release-notes.sh) + echo "RELEASE_NOTES<> $GITHUB_ENV + echo "${version_release_notes}" >> $GITHUB_ENV + echo "EOF" >> $GITHUB_ENV + + - name: Log-in to ghcr.io registry + uses: docker/login-action@v2 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Add tags to the Docker image + id: meta + uses: docker/metadata-action@v4 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=semver,pattern={{version}},value=${{ env.semantic_version }} + + - name: Push Docker image + uses: docker/build-push-action@v3 + with: + context: . + file: docker/service.Dockerfile + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + + - name: Publish GitHub release + uses: ncipollo/release-action@v1 + with: + body: ${{ env.RELEASE_NOTES }} + commit: main + name: Version ${{ env.semantic_version }} + tag: ${{ env.semantic_version }} diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml new file mode 100644 index 0000000..f58a5b2 --- /dev/null +++ b/.github/workflows/run_tests.yml @@ -0,0 +1,42 @@ +# This workflow will build the service and test Docker images for HOSS, then +# run the Python `unittest` suite within a test Docker container, reporting +# test results and code coverage as artefacts. It will be called by the +# workflow that run tests against new PRs and as a first step in the workflow +# that publishes new Docker images. +name: Run Python unit tests + +on: + workflow_call + +jobs: + build_and_test: + runs-on: ubuntu-latest + strategy: + fail-fast: false + + steps: + - name: Checkout harmony-opendap-subsetter repository + uses: actions/checkout@v3 + with: + lfs: true + + - name: Build service image + run: ./bin/build-image + + - name: Build test image + run: ./bin/build-test + + - name: Run test image + run: ./bin/run-test + + - name: Archive test results + uses: actions/upload-artifact@v3 + with: + name: Test results + path: test-reports/ + + - name: Archive coverage report + uses: actions/upload-artifact@v3 + with: + name: Coverage report + path: coverage/* diff --git a/.github/workflows/run_tests_on_pull_requests.yml b/.github/workflows/run_tests_on_pull_requests.yml new file mode 100644 index 0000000..a948fd1 --- /dev/null +++ b/.github/workflows/run_tests_on_pull_requests.yml @@ -0,0 +1,13 @@ +# This workflow will run when a PR is opened against the `main` branch. It will +# trigger the reusable workflow in `.github/workflows/run_tests.yml`, which +# builds the service and test Docker images, and runs the `unittest` suite in a +# Docker container built from the test image. +name: Run Python unit tests for pull requests against main + +on: + pull_request: + branches: [ main ] + +jobs: + build_and_test: + uses: ./.github/workflows/run_tests.yml diff --git a/README.md b/README.md index 6f83163..7ff0c2a 100644 --- a/README.md +++ b/README.md @@ -210,8 +210,35 @@ GitHub. ## CI/CD: -This section will be edited when the CI/CD for HOSS is migrated from Bamboo to -GitHub workflows. +The CI/CD for HOSS is contained in GitHub workflows in the `.github/workflows` +directory: + +* `run_tests.yml` - A reusable workflow that builds the service and test Docker + images, then runs the Python unit test suite in an instance of the test + Docker container. +* `run_tests_on_pull_requests.yml` - Triggered for all PRs against the `main` + branch. It runs the workflow in `run_tests.yml` to ensure all tests pass for + the new code. +* `publish_docker_image.yml` - Triggered either manually or for commits to the + `main` branch that contain changes to the `docker/service_version.txt` file. + +The `publish_docker_image.yml` workflow will: + +* Run the full unit test suite, to prevent publication of broken code. +* Extract the semantic version number from `docker/service_version.txt`. +* Extract the release notes for the most recent version from `CHANGELOG.md` +* Build the service Docker image and push it to the GitHub Container Registry. +* Create a GitHub release that will also tag the related git commit with the + semantic version number. + +Before triggering a release, ensure both the `docker/service_version.txt` and +`CHANGELOG.md` files are updated. The `CHANGELOG.md` file requires a specific +format for a new release, as it looks for the following string to define the +newest release of the code (starting at the top of the file). + +``` +## vX.Y.Z +``` ## Get in touch: diff --git a/bin/extract-release-notes.sh b/bin/extract-release-notes.sh new file mode 100755 index 0000000..87725d5 --- /dev/null +++ b/bin/extract-release-notes.sh @@ -0,0 +1,22 @@ +#!/bin/bash +############################################################################### +# +# A bash script to extract only the notes related to the most recent version of +# HOSS from CHANGELOG.md +# +# 2023-06-16: Created. +# 2023-10-10: Copied from earthdata-varinfo repository to HOSS. +# +############################################################################### + +CHANGELOG_FILE="CHANGELOG.md" +VERSION_PATTERN="^## v" +# Count number of versions in version file: +number_of_versions=$(grep -c "${VERSION_PATTERN}" ${CHANGELOG_FILE}) + +if [ ${number_of_versions} -gt 1 ] +then + grep -B 9999 -m 2 "${VERSION_PATTERN}" ${CHANGELOG_FILE} | sed '$d' | sed '$d' +else + cat ${CHANGELOG_FILE} +fi