From c0a275d12058fb2f9ef8f57263bffde840d44638 Mon Sep 17 00:00:00 2001 From: Owen Littlejohns Date: Wed, 3 Jan 2024 15:59:47 -0500 Subject: [PATCH] DAS-2043 - Add GitHub workflows for CI/CD. --- .github/pull_request_template.md | 2 +- .github/workflows/publish_docker_image.yml | 83 +++++++++++++++++++ .github/workflows/run_tests.yml | 42 ++++++++++ .../workflows/run_tests_on_pull_requests.yml | 13 +++ README.md | 38 +++++++++ bin/extract-release-notes.sh | 23 +++++ 6 files changed, 200 insertions(+), 1 deletion(-) 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/pull_request_template.md b/.github/pull_request_template.md index 2cee128..8e6f556 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -11,6 +11,6 @@ A short description of the changes in this PR. ## PR Acceptance Checklist * [ ] Jira ticket acceptance criteria met. * [ ] `CHANGELOG.md` updated to include high level summary of PR changes. -* [ ] `VERSION` updated if publishing a release. +* [ ] `docker/service_version.txt` updated if publishing a release. * [ ] Tests added/updated and passing. * [ ] Documentation updated (if needed). diff --git a/.github/workflows/publish_docker_image.yml b/.github/workflows/publish_docker_image.yml new file mode 100644 index 0000000..476bc1e --- /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 Swath Projector. +name: Publish Swath Projector 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-swath-projector 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..6813800 --- /dev/null +++ b/.github/workflows/run_tests.yml @@ -0,0 +1,42 @@ +# This workflow will build the service and test Docker images for the Swath +# Projector, 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-swath-projector 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 caf8dbb..3560494 100644 --- a/README.md +++ b/README.md @@ -171,3 +171,41 @@ The general rules for which version number to increment are: When the Docker image is built, it will be tagged with the semantic version number as stored in `docker/service_version.txt`. + +## CI/CD: + +The CI/CD for the Swath Projector 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_request.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 tests 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`. +* 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: + +You can reach out to the maintainers of this repository via email: + +* david.p.auty@nasa.gov +* owen.m.littlejohns@nasa.gov diff --git a/bin/extract-release-notes.sh b/bin/extract-release-notes.sh new file mode 100755 index 0000000..00cbf40 --- /dev/null +++ b/bin/extract-release-notes.sh @@ -0,0 +1,23 @@ +#!/bin/bash +############################################################################### +# +# A bash script to extract only the notes related to the most recent version of +# the Swath Projector from CHANGELOG.md +# +# 2023-06-16: Created. +# 2023-10-10: Copied from earthdata-varinfo repository to HOSS. +# 2024-01-03: Copied from HOSS repository to the Swath Projector. +# +############################################################################### + +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