From c9c4a51d530d2c8684584f50290be6b557e1dfcf Mon Sep 17 00:00:00 2001 From: Darren Kelly <107671032+darrenvechain@users.noreply.github.com> Date: Tue, 26 Mar 2024 16:09:24 +0000 Subject: [PATCH] Enable custom ghcr images (#683) * feat: allow devs to publish images from branches * feat: publshing docker images on master commits, pre-release, and release * fix: typo * Update .github/workflows/on-master-commit.yaml Co-authored-by: Pedro Gomes * Update .github/workflows/on-master-commit.yaml Co-authored-by: Pedro Gomes * fix: remove duplication * chore: update actions versions * feat: orchestract pull request CI from one file * feat: orchestract pull request CI from one file * fix: typos * fix: remove requirement for test to pass before testing docker build * Update .github/workflows/on-master-commit.yaml Co-authored-by: libotony * Update .github/workflows/on-pre-release.yaml Co-authored-by: libotony * chore: add linter to pre-master publish * feat: throw an error for invalid release tag * feat: throw an error for invalid release tag * fix: publish only rc for pre-release" * fix: pre-release regex * fix: remove duplication * feat: verify tags/releases * fix: validate step * chore: update to use ref_name instead of ref * Update .github/workflows/on-release.yaml Co-authored-by: libotony * Update .github/workflows/on-pull-request.yaml Co-authored-by: libotony * chore: updates for PR comments --------- Co-authored-by: Pedro Gomes Co-authored-by: libotony --- .github/workflows/lint-go.yaml | 6 +- .github/workflows/on-master-commit.yaml | 48 +++++++++++++ .github/workflows/on-pre-release.yaml | 43 ++++++++++++ .github/workflows/on-pull-request.yaml | 29 ++++++++ .github/workflows/on-release.yaml | 60 ++++++++++++++++ .github/workflows/publish-docker-images.yaml | 73 ++++++++++++++++++++ .github/workflows/release-docker.yaml | 57 --------------- .github/workflows/test-docker-build.yaml | 31 --------- .github/workflows/test.yaml | 22 +++--- 9 files changed, 263 insertions(+), 106 deletions(-) create mode 100644 .github/workflows/on-master-commit.yaml create mode 100644 .github/workflows/on-pre-release.yaml create mode 100644 .github/workflows/on-pull-request.yaml create mode 100644 .github/workflows/on-release.yaml create mode 100644 .github/workflows/publish-docker-images.yaml delete mode 100644 .github/workflows/release-docker.yaml delete mode 100644 .github/workflows/test-docker-build.yaml diff --git a/.github/workflows/lint-go.yaml b/.github/workflows/lint-go.yaml index 408e01ae5..79d4d87f3 100644 --- a/.github/workflows/lint-go.yaml +++ b/.github/workflows/lint-go.yaml @@ -1,10 +1,8 @@ name: Lint on: - push: - branches: - - master - pull_request: + # Should only be used by other workflows + workflow_call: permissions: contents: read diff --git a/.github/workflows/on-master-commit.yaml b/.github/workflows/on-master-commit.yaml new file mode 100644 index 000000000..2770b6350 --- /dev/null +++ b/.github/workflows/on-master-commit.yaml @@ -0,0 +1,48 @@ +name: Master branch CI + +on: + push: + branches: + - 'master' + +jobs: + run-unit-tests: + name: Run Unit Tests + uses: ./.github/workflows/test.yaml + + lint: + name: Lint + uses: ./.github/workflows/lint-go.yaml + + generate-tags: + name: Generate Docker Tags + runs-on: ubuntu-latest + outputs: + tag_date: ${{ steps.tag_date.outputs.tag_date }} + short_sha: ${{ steps.short_sha.outputs.short_sha }} + steps: + - name: Generate Tag Date + id: tag_date + run: echo "tag_date=$(date +'%Y%m%d')" >> "$GITHUB_OUTPUT" + - name: Generate Short SHA + id: short_sha + run: echo "short_sha=$(echo $GITHUB_SHA | cut -c1-7)" >> "$GITHUB_OUTPUT" + + publish-docker-image: + name: Publish Docker Image + uses: ./.github/workflows/publish-docker-images.yaml + secrets: inherit + needs: + - run-unit-tests + - generate-tags + - lint + permissions: + contents: read + packages: write + with: + images: | + ghcr.io/${{ github.repository }} + # eg: master-20240321-7d8e9f2 + tags: | + type=raw,value=master-${{ needs.generate-tags.outputs.tag_date }}-${{ needs.generate-tags.outputs.short_sha }} + type=raw,value=master-latest diff --git a/.github/workflows/on-pre-release.yaml b/.github/workflows/on-pre-release.yaml new file mode 100644 index 000000000..94988ee03 --- /dev/null +++ b/.github/workflows/on-pre-release.yaml @@ -0,0 +1,43 @@ +name: Pre-Release CI + +on: + push: + tags: + - 'v*.*.*-rc.*' + +jobs: + + validate: + name: Validate Release + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Validate Tag + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # This step validates that the tag is a pre-release + run: | + prerelease=$(gh release view ${{ github.ref_name }} --json isPrerelease | jq -r '.isPrerelease') + if [ "$prerelease" != "true" ]; then + echo "Tag is not a pre-release" + exit 1 + fi + + publish-docker-image: + name: Publish Pre-Release Docker Image + uses: ./.github/workflows/publish-docker-images.yaml + secrets: inherit + needs: + - validate + permissions: + contents: read + packages: write + with: + environment: docker-publish + images: | + ${{ github.repository }} + ghcr.io/${{ github.repository }} + tags: | + type=raw,value=${{ github.ref_name }} diff --git a/.github/workflows/on-pull-request.yaml b/.github/workflows/on-pull-request.yaml new file mode 100644 index 000000000..143d08bdf --- /dev/null +++ b/.github/workflows/on-pull-request.yaml @@ -0,0 +1,29 @@ +name: Pull Request CI + +on: + pull_request: + branches: + - master + +jobs: + run-unit-tests: + name: Run Unit Tests + uses: ./.github/workflows/test.yaml + + lint: + name: Lint + uses: ./.github/workflows/lint-go.yaml + + # This doesn't publish the image, it just tests the publishing workflow (build the image / tags / labels) + test-docker-publish: + name: Test Docker Publish + uses: ./.github/workflows/publish-docker-images.yaml + secrets: inherit + permissions: + contents: read + packages: write + with: + images: | + ghcr.io/${{ github.repository }} + tags: | + type=raw,value=${{ github.ref }}-${{ github.sha }} diff --git a/.github/workflows/on-release.yaml b/.github/workflows/on-release.yaml new file mode 100644 index 000000000..2b4007dd4 --- /dev/null +++ b/.github/workflows/on-release.yaml @@ -0,0 +1,60 @@ +name: Release CI + +on: + push: + tags: + - 'v*.*.*' + - '!v*.*.*-rc*' + +jobs: + validate: + runs-on: ubuntu-latest + name: Validate Release + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: '20' + + - name: Validate Tag + run: | + node -e "if (!/^v\d+\.\d+\.\d+$/.test('${{ github.ref_name }}')) { console.error('Invalid version provided');process.exit(1);}" + + - name: Validate VERSION + run: | + if [ "$(cat cmd/thor/VERSION)" != "${{ github.ref_name }}" ]; then + echo "VERSION file does not match tag" + exit 1 + fi + + - name: Validate Release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # This step validates that the tag is an official release + run: | + prerelease=$(gh release view ${{ github.ref_name }} --json isPrerelease | jq -r '.isPrerelease') + if [ "$prerelease" != "false" ]; then + echo "Tag is not an official release" + exit 1 + fi + + publish-docker-image: + name: Publish Docker Image + uses: ./.github/workflows/publish-docker-images.yaml + secrets: inherit + needs: + - validate + permissions: + contents: read + packages: write + with: + environment: docker-publish + images: | + ${{ github.repository }} + ghcr.io/${{ github.repository }} + tags: | + type=raw,value=${{ github.event.release.tag_name }} + type=raw,value=latest diff --git a/.github/workflows/publish-docker-images.yaml b/.github/workflows/publish-docker-images.yaml new file mode 100644 index 000000000..7362928dd --- /dev/null +++ b/.github/workflows/publish-docker-images.yaml @@ -0,0 +1,73 @@ +name: Publish Docker Image + +on: + workflow_call: + inputs: + environment: + type: string + required: false + description: 'The environment to publish the Docker image to.' + tags: + type: string + required: true + description: 'The tags to apply to the Docker image.' + images: + type: string + required: true + description: 'The images to publish' + workflow_dispatch: + +jobs: + build-and-push-image: + name: Build and Push Docker Image + runs-on: ubuntu-latest + + permissions: + contents: read + packages: write + + environment: ${{ inputs.environment }} + steps: + + - name: Checkout Repo + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + # Only log in to Docker Hub if the event is a release + if: ${{ inputs.environment == 'docker-publish' }} + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + # default to ghcr.io for workflow_dispatch + images: ${{ inputs.images || format('ghcr.io/{0}', github.repository) }} + # use the branch + sha if workflow_dispatch + tags: ${{ inputs.tags || format('type=raw,value={0}-{1}', github.ref_name, github.sha) }} + + - name: Push to Registry(s) + uses: docker/build-push-action@v5 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + provenance: false + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/release-docker.yaml b/.github/workflows/release-docker.yaml deleted file mode 100644 index 713e54e46..000000000 --- a/.github/workflows/release-docker.yaml +++ /dev/null @@ -1,57 +0,0 @@ -name: Publish docker image - -on: - push: - tags: - - 'v*' - -jobs: - push_to_registries: - runs-on: ubuntu-latest - permissions: - packages: write - contents: read - - environment: docker-publish - - steps: - - uses: actions/checkout@v3 - - # Add support for more platforms with QEMU (optional) - # https://github.com/docker/setup-qemu-action - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - - name: Log in to Docker Hub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Log in to the Container registry - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata (tags, labels) for Docker - id: meta - uses: docker/metadata-action@v4 - with: - images: | - vechain/thor - ghcr.io/${{ github.repository }} - - - name: Build and push - uses: docker/build-push-action@v4 - with: - context: . - platforms: linux/amd64,linux/arm64 - push: true - provenance: false - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/test-docker-build.yaml b/.github/workflows/test-docker-build.yaml deleted file mode 100644 index 01f925a50..000000000 --- a/.github/workflows/test-docker-build.yaml +++ /dev/null @@ -1,31 +0,0 @@ -name: Test Docker Buld - -on: - push: - branches: - - master - pull_request: - branches: - - master - -jobs: - docker_build: - runs-on: ubuntu-latest - name: Test Build - - steps: - - uses: actions/checkout@v3 - - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - - name: Build and push - uses: docker/build-push-action@v4 - with: - context: . - platforms: linux/amd64,linux/arm64 - push: false - provenance: false diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index ec9c475f6..495be30f0 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -1,14 +1,8 @@ name: Unit Tests -on: - push: - branches: - - 'master' - - 'master-*' - - pull_request: - branches: - - master +on: + # Should only be used by other workflows + workflow_call: jobs: unit_tests: @@ -18,9 +12,9 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] include: - go-version: 1.19.x - os: ubuntu-latest + os: ubuntu-latest - go-version: 1.20.x - os: ubuntu-latest + os: ubuntu-latest runs-on: ${{ matrix.os }} steps: - name: Checkout code @@ -33,11 +27,11 @@ jobs: - name: Make all run: make all - + - name: Make Test id: unit-test run: make test - + - name: Post To Slack if: always() && github.ref == 'refs/heads/master' && (steps.unit-test.outcome == 'failure') uses: slackapi/slack-github-action@v1.24.0 @@ -52,7 +46,7 @@ jobs: env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} test_coverage: - runs-on: ubuntu-latest + runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3