diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..f354527 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,174 @@ +name: Docker image build. + +on: + workflow_dispatch: + push: + paths-ignore: + - '**.md' + branches: + - "master" + - "main" + +env: + ENABLE_CODE_LINT: false + ENABLE_CODE_SCANS: false + DEPLOY: false + +jobs: + prepare: + name: Preparing build context + runs-on: ubuntu-latest + outputs: + SANITISED_REPOSITORY_NAME: ${{ steps.get_env.outputs.SANITISED_REPOSITORY_NAME }} + DOCKER_IMAGE: ${{ steps.get_env.outputs.DOCKER_IMAGE }} + GITHUB_COMMIT_NUMBER: ${{ steps.get_env.outputs.GITHUB_COMMIT_NUMBER }} + GITHUB_SHA: ${{ steps.get_env.outputs.GITHUB_SHA }} + GITHUB_RUN_ID: ${{ steps.get_env.outputs.GITHUB_RUN_ID }} + RELEASE_VERSION: ${{ steps.get_env.outputs.RELEASE_VERSION }} + steps: + - name: Checkout repo + uses: actions/checkout@v2 + with: + fetch-depth: '0' + - name: Setting environment variables + id: get_env + run: | + TMP_SANITISED_REPOSITORY_NAME=$(echo ${{ github.event.repository.name }} | sed -e 's|\.|-|g') + TMP_GITHUB_COMMITS_COUNT=$(git rev-list --count HEAD) + TMP_GITHUB_COUNT_NUMBER=$(echo ${GITHUB_RUN_NUMBER}) + echo "::set-output name=SANITISED_REPOSITORY_NAME::$TMP_SANITISED_REPOSITORY_NAME" + echo "::set-output name=DOCKER_IMAGE::ghcr.io/${{ github.repository_owner }}/$TMP_SANITISED_REPOSITORY_NAME" + echo "::set-output name=GITHUB_COMMIT_NUMBER::$TMP_GITHUB_COMMITS_COUNT" + echo "::set-output name=GITHUB_SHA::$(echo ${GITHUB_SHA::8})" + echo "::set-output name=GITHUB_RUN_ID::$TMP_GITHUB_COUNT_NUMBER" + echo "::set-output name=RELEASE_VERSION::1.$TMP_GITHUB_COMMITS_COUNT.$TMP_GITHUB_COUNT_NUMBER" + + test: + needs: [ prepare ] + name: Code checks pipeline + runs-on: ubuntu-20.04 + container: github/super-linter:v3.15.5 + env: + CI: true + steps: + - name: Checkout repo + uses: actions/checkout@v2 + - name: Configure git for private modules + run: | + git config --global url."https://${{ secrets.GHCR_TOKEN }}:x-oauth-basic@github.com/${{ github.repository_owner }}".insteadOf "https://github.com/${{ github.repository_owner }}" + - name: Lint Code Base + if: env.ENABLE_CODE_LINT == true + env: + VALIDATE_ALL_CODEBASE: true + VALIDATE_DOCKERFILE: false # this leaves us with hadolint only + VALIDATE_GO: false # disable bulk validation of go files, run the linter manually + DEFAULT_BRANCH: main + GITHUB_TOKEN: ${{ secrets.GHCR_TOKEN }} + LOG_LEVEL: WARN + run: | + golangci-lint run --exclude-use-default ./... + /action/lib/linter.sh + - name: Run unit tests + run: | + make test CI_RUN=${CI} + + code_scans: + needs: [ prepare ] + name: Code scans pipeline + runs-on: ubuntu-20.04 + steps: + - name: Checkout repo + uses: actions/checkout@v2 + - name: Configure git for private modules + run: | + git config --global url."https://${{ secrets.GHCR_TOKEN }}:x-oauth-basic@github.com/${{ github.repository_owner }}".insteadOf "https://github.com/${{ github.repository_owner }}" + make update + - name: WriteGoList + run: go list -json -m all > go.list + - name: Running nancy + if: env.ENABLE_CODE_SCANS == true + uses: sonatype-nexus-community/nancy-github-action@main + - name: Running gosec + if: env.ENABLE_CODE_SCANS == true + uses: securego/gosec@master + with: + args: ./... + + build: + needs: [ prepare, test, code_scans ] + name: Docker image build (multiarch) + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v2 + - name: Set up QEMU + uses: docker/setup-qemu-action@v1 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + - name: Login to GHCR + if: github.event_name != 'pull_request' + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.ACTOR }} + password: ${{ secrets.GHCR_TOKEN }} + - name: Prepare for push + id: prep + run: | + TAGS="${{ needs.prepare.outputs.DOCKER_IMAGE }}:${{ needs.prepare.outputs.GITHUB_SHA }},${{ needs.prepare.outputs.DOCKER_IMAGE }}:${{ needs.prepare.outputs.RELEASE_VERSION }},${{ needs.prepare.outputs.DOCKER_IMAGE }}:latest" + echo ::set-output name=tags::${TAGS} + BRANCH=$(echo ${GITHUB_REF##*/} | tr '[A-Z]' '[a-z]') + LABELS="org.opencontainers.image.revision=${{ needs.prepare.outputs.GITHUB_SHA }}" + LABELS="$LABELS,org.opencontainers.image.created=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" + LABELS="$LABELS,org.opencontainers.image.version=$VERSION" + LABELS="$LABELS,com.github.repo.branch=$BRANCH" + LABELS="$LABELS,com.github.repo.dockerfile=Dockerfile" + echo ::set-output name=labels::${LABELS} + BUILD_ARGS="BRANCH=$BRANCH" + echo ::set-output name=args::${BUILD_ARGS} + - name: Build image + id: docker_build + uses: docker/build-push-action@v2 + with: + builder: ${{ steps.buildx.outputs.name }} + platforms: linux/arm64,linux/amd64 + push: ${{ github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' }} + tags: ${{ steps.prep.outputs.tags }} + build-args: | + GITHUB_AUTH_TOKEN=${{ secrets.GHCR_TOKEN }} + MICROSERVICE_NAME=${{ github.event.repository.name }} + GITHUB_COMMIT_NUMBER=${{ needs.prepare.outputs.GITHUB_COMMIT_NUMBER }} + GITHUB_SHA=${{ needs.prepare.outputs.GITHUB_SHA }} + ${{ steps.prep.outputs.args }} + labels: ${{ steps.prep.outputs.labels }} + no-cache: false + - name: Scan image + uses: anchore/scan-action@v2 + if: ${{ github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' }} + with: + image: "${{ needs.prepare.outputs.DOCKER_IMAGE }}:${{ needs.prepare.outputs.GITHUB_SHA }}" + fail-build: true + + release: + name: Create Release + runs-on: ubuntu-latest + needs: [ prepare, deploy ] + steps: + - name: Checkout code + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Get list of the commits since last release + run: | + echo "$(git log $(git describe --tags --abbrev=0)..HEAD --pretty=format:"%h %s")" > .release_notes + - name: Create Release + id: create_release + uses: actions/create-release@main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: v${{ github.event.repository.name }}/${{ needs.prepare.outputs.RELEASE_VERSION }} + release_name: v${{ needs.prepare.outputs.RELEASE_VERSION }} + body_path: .release_notes + draft: false + prerelease: ${{ github.ref != 'refs/heads/master' && github.ref != 'refs/heads/main' }} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a56aa1d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +# syntax=docker/dockerfile:1.2.1-labs + +FROM golang:1-alpine as baseimg + +RUN apk add make +WORKDIR /go/src/app +ENV GO111MODULE=on CGO_ENABLED=1 GOOS=linux +COPY . /go/src/app/ +RUN make + +FROM alpine:latest +RUN apk add --no-cache ca-certificates +WORKDIR /go/src/app +COPY --from=baseimg /go/src/app/semver-gen . +COPY --from=baseimg /go/src/app/config-release.yaml config.yaml + +CMD ["./semver-gen"] \ No newline at end of file diff --git a/config-release.yaml b/config-release.yaml new file mode 100644 index 0000000..db2a72b --- /dev/null +++ b/config-release.yaml @@ -0,0 +1,14 @@ +version: 1 +force: + major: 1 +wording: + patch: + - update + - initial + - fix + minor: + - add + - change + - improve + major: + - breaking \ No newline at end of file diff --git a/config.yaml b/config.yaml index c785f3a..62e4b47 100644 --- a/config.yaml +++ b/config.yaml @@ -5,6 +5,7 @@ wording: patch: - update - initial + - fix minor: - add - change