From d71e1e812ae0213be7eb0aba41dba447732961ca Mon Sep 17 00:00:00 2001 From: Ryan Faircloth Date: Wed, 29 Jun 2022 14:10:04 -0400 Subject: [PATCH] ci: Enhancements to CI and release fixes #408 fixes #423 This PR makes several changes to the CI* Adds PR lint to ensure conventional commit syntax is used for all PRs Uses semantic-release tool to review commit log on branch and generate version numbers Publishes containers (non pr) to ghcr.io Publishes release containers to hub.docker.com Completes common tags (versions, sha-1 and ref) on all branches Notes Unable to test actually publishing containers to dockerhub however this was taken from a similar working project. --- .github/dependabot.yml | 11 ++ .github/workflows/ci-main.yml | 206 ++++++++++++++++++++++++++++++++ .github/workflows/pr-lint.yml | 17 +++ .github/workflows/run-tests.yml | 54 --------- .releaserc | 46 +++++++ Dockerfile | 15 +-- 6 files changed, 282 insertions(+), 67 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/ci-main.yml create mode 100644 .github/workflows/pr-lint.yml delete mode 100644 .github/workflows/run-tests.yml create mode 100644 .releaserc diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..5b06320 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "maven" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "daily" diff --git a/.github/workflows/ci-main.yml b/.github/workflows/ci-main.yml new file mode 100644 index 0000000..1925c6e --- /dev/null +++ b/.github/workflows/ci-main.yml @@ -0,0 +1,206 @@ +name: Main CI +on: + push: + branches: + - "master" + - "develop" + pull_request: + branches: + - "*" +jobs: + meta: + runs-on: ubuntu-latest + outputs: + dockerhub-publish: ${{ steps.dockerhub-publish.outputs.defined }} + registry: ghcr.io/${{ github.repository }}/container:${{ fromJSON(steps.docker_action_meta.outputs.json).labels['org.opencontainers.image.version'] }} + container_tags: ${{ steps.docker_action_meta.outputs.tags }} + container_labels: ${{ steps.docker_action_meta.outputs.labels }} + container_buildtime: ${{ fromJSON(steps.docker_action_meta.outputs.json).labels['org.opencontainers.image.created'] }} + container_version: ${{ fromJSON(steps.docker_action_meta.outputs.json).labels['org.opencontainers.image.version'] }} + container_revision: ${{ fromJSON(steps.docker_action_meta.outputs.json).labels['org.opencontainers.image.revision'] }} + container_base: ${{ fromJSON(steps.docker_action_meta.outputs.json).tags[0] }} + new_release_version: ${{ steps.version.outputs.new_release_version }} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: false + persist-credentials: false + - id: dockerhub-publish + if: "${{ env.MY_KEY != '' }}" + run: echo "::set-output name=defined::true" + env: + MY_KEY: ${{ secrets.DOCKER_PASS }} + - uses: actions/setup-node@v2 + with: + node-version: "14" + - name: Semantic Release + id: version + uses: cycjimmy/semantic-release-action@v3.0.0 + with: + semantic_version: 17 + extra_plugins: | + @semantic-release/exec + @semantic-release/git + @google/semantic-release-replace-plugin + conventional-changelog-conventionalcommits + dry_run: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Docker meta + id: docker_action_meta + uses: docker/metadata-action@v4.0.1 + with: + images: ghcr.io/${{ github.repository }}/container + flavor: | + latest=false + tags: | + type=sha,format=long + type=sha + type=semver,pattern={{version}},value=${{ steps.version.outputs.new_release_version }} + type=semver,pattern={{major}},value=${{ steps.version.outputs.new_release_version }} + type=semver,pattern={{major}}.{{minor}},value=${{ steps.version.outputs.new_release_version }} + type=ref,event=branch + type=ref,event=pr + type=ref,event=tag + labels: | + org.opencontainers.image.licenses=Apache-2.0 + runTests: + runs-on: ubuntu-latest + needs: [meta] + steps: + - uses: actions/checkout@v2 + with: + submodules: "recursive" + + # These steps are quick and will work or if fail only because of external issues + - uses: actions/setup-java@v2 + with: + distribution: "temurin" + java-version: "11" + cache: "maven" + - uses: actions/setup-python@v4 + with: + python-version: "3.8" + cache: "pip" + + #Run tests + - name: Maven Set version + run: | + mvn versions:set -DnewVersion=${{ needs.meta.outputs.new_release_version }} + - name: Maven Package + run: | + mvn package -DskipTests + - name: Maven Test + run: | + mvn test + - name: Other Test + run: | + ./src/test/resources/run-s3-tests.sh + + #Store the target + - uses: actions/upload-artifact@v2 + with: + name: s3proxy + path: target/s3proxy + - uses: actions/upload-artifact@v2 + with: + name: pom + path: pom.xml + + Containerize: + runs-on: ubuntu-latest + needs: [runTests, meta] + steps: + #Yes we need code + - uses: actions/checkout@v2 + - uses: actions/download-artifact@v2 + with: + name: s3proxy + path: target + - uses: actions/download-artifact@v2 + with: + name: pom + path: . + # These steps are quick and will work or if fail only because of external issues + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Login to DockerHub + uses: docker/login-action@v2.0.0 + if: github.event_name != 'pull_request' && needs.meta.outputs.dockerhub-publish == 'true' + with: + username: ${{ secrets.DOCKER_USER }} + password: ${{ secrets.DOCKER_PASS }} + + - name: Login to DockerHub + uses: docker/login-action@v2.0.0 + if: github.event_name != 'pull_request' + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + #Generate Meta + - name: Build and push + uses: docker/build-push-action@v3 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ needs.meta.outputs.container_base }} + labels: ${{ needs.meta.outputs.container_labels }} + build-args: | + BUILDTIME=${{ needs.meta.outputs.container_buildtime }} + VERSION=${{ needs.meta.outputs.container_version }} + REVISION=${{ needs.meta.outputs.container_revision }} + cache-from: type=registry,ref=${{ needs.meta.outputs.container_base }} + cache-to: type=inline + - uses: actions/setup-node@v2 + with: + node-version: "14" + - name: Semantic Release + if: github.event_name != 'pull_request' && needs.meta.outputs.dockerhub-publish == 'true' + id: version + uses: cycjimmy/semantic-release-action@v3.0.0 + with: + semantic_version: 17 + extra_plugins: | + @semantic-release/exec + @semantic-release/git + conventional-changelog-conventionalcommits + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Setup regctl + if: github.event_name != 'pull_request' && needs.meta.outputs.dockerhub-publish == 'true' + run: | + curl -L https://github.com/regclient/regclient/releases/download/v0.3.5/regctl-linux-amd64 >/tmp/regctl + chmod 755 /tmp/regctl + + - name: Docker meta + if: github.event_name != 'pull_request' && needs.meta.outputs.dockerhub-publish == 'true' + id: docker_action_meta + uses: docker/metadata-action@v4.0.1 + with: + images: andrewgaul/s3proxy + flavor: | + latest=false + tags: | + type=sha + type=semver,pattern={{version}},value=${{ needs.meta.outputs.new_release_version }} + type=semver,pattern={{major}},value=${{ needs.meta.outputs.new_release_version }} + type=semver,pattern={{major}}.{{minor}},value=${{ needs.meta.outputs.new_release_version }} + type=ref,event=branch + type=ref,event=pr + type=ref,event=tag + labels: | + org.opencontainers.image.licenses=Apache-2.0 + - name: Publish to Docker + if: github.event_name != 'pull_request' && needs.meta.outputs.dockerhub-publish == 'true' + run: | + for line in $CONTAINER_DEST_TAGS; do echo working on "$line"; /tmp/regctl image copy $SOURCE_CONTAINER $line; done + env: + SOURCE_CONTAINER: ${{ needs.meta.outputs.new_release_version }} + CONTAINER_DEST_TAGS: ${{ steps.docker_action_meta.outputs.tags }} diff --git a/.github/workflows/pr-lint.yml b/.github/workflows/pr-lint.yml new file mode 100644 index 0000000..ad6df65 --- /dev/null +++ b/.github/workflows/pr-lint.yml @@ -0,0 +1,17 @@ +name: "Lint PR" + +on: + pull_request_target: + types: + - opened + - edited + - synchronize + +jobs: + main: + name: Validate PR title + runs-on: ubuntu-latest + steps: + - uses: amannn/action-semantic-pull-request@v4 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml deleted file mode 100644 index 4ecd7a7..0000000 --- a/.github/workflows/run-tests.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: Run Tests -on: - push: - branches: - - 'master' - tags: - - '*' - pull_request: - branches: - - '*' -jobs: - runTests: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - submodules: 'recursive' - - name: Set up QEMU - uses: docker/setup-qemu-action@v1 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 - - uses: actions/setup-java@v2 - with: - distribution: 'temurin' - java-version: '11' - - name: Install dependencies - run: sudo apt-get install -y libevent-dev python3-pip python3-virtualenv - - name: Run Tests Tests - run: | - mvn package - ./src/test/resources/run-s3-tests.sh - - name: Login to DockerHub - uses: docker/login-action@v1 - if: github.event_name != 'pull_request' - with: - username: ${{ secrets.DOCKER_USER }} - password: ${{ secrets.DOCKER_PASS }} - - name: Docker meta - id: meta - uses: docker/metadata-action@v3 - with: - images: andrewgaul/s3proxy - tags: | - type=sha,event=branch - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=semver,pattern={{major}} - - name: Build and push - uses: docker/build-push-action@v2 - with: - context: . - platforms: linux/amd64,linux/arm64 - push: ${{ github.event_name != 'pull_request' }} - tags: ${{ steps.meta.outputs.tags }} diff --git a/.releaserc b/.releaserc new file mode 100644 index 0000000..a05ac08 --- /dev/null +++ b/.releaserc @@ -0,0 +1,46 @@ +{ + "tagFormat": 's3proxy-${version}', + "branches": [ + { + "name": 'master', + prerelease: false + }, + { + "name": 'releases\/+([0-9])?(\.\d+)(\.\d+|z|$)', + prerelease: false + }, + { + "name": 'next', + prerelease: false + }, + { + name: 'next-major', + prerelease: true + }, + { + name: 'develop', + prerelease: true + }, + { + name: 'develop\/.*', + prerelease: true + } + ], + plugins: [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "presetConfig": "conventional-changelog-conventionalcommits" + } + ], + "@semantic-release/release-notes-generator", + ["@semantic-release/git", { + "assets": [ + "pom.xml", + ], + "message": "chore(release): ${nextRelease.version}\n\n${nextRelease.notes}" + }], + ["@semantic-release/github"], + ] +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index fffae63..4378aae 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,22 +1,11 @@ -# Multistage - Builder -FROM maven:3.6.3-jdk-11-slim as s3proxy-builder -LABEL maintainer="Andrew Gaul " - -WORKDIR /opt/s3proxy -COPY . /opt/s3proxy/ - -RUN mvn package -DskipTests - -# Multistage - Image FROM openjdk:11-jre-slim LABEL maintainer="Andrew Gaul " WORKDIR /opt/s3proxy COPY \ - --from=s3proxy-builder \ - /opt/s3proxy/target/s3proxy \ - /opt/s3proxy/src/main/resources/run-docker-container.sh \ + target/s3proxy \ + src/main/resources/run-docker-container.sh \ /opt/s3proxy/ ENV \