name: Test, scan, build, release on: workflow_dispatch: push: paths-ignore: - '**.md' - '**/release.yaml' branches: - "master" - "main" env: ENABLE_CODE_LINT: false ENABLE_CODE_SCANS: false DEPLOY: false GO_VERSION: 1.19 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@v3 with: fetch-depth: '0' - name: Setting environment variables id: get_env run: | DOWNLOAD_URL=$(curl -s https://api.github.com/repos/lukaszraczylo/semver-generator/releases/latest | grep -E ".*browser_download_url.*linux-" | grep -vE "(arm64|md5)" \ | cut -d '"' -f 4) curl -s -L -o semver-gen "$DOWNLOAD_URL" && chmod +x semver-gen 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}) TMP_RELEASE_VERSION=$(./semver-gen generate -l -c config-release.yaml | sed -e 's|SEMVER ||g') # Setting outputs echo "SANITISED_REPOSITORY_NAME=$TMP_SANITISED_REPOSITORY_NAME" > $GITHUB_OUTPUT echo "DOCKER_IMAGE=ghcr.io/${{ github.repository_owner }}/$TMP_SANITISED_REPOSITORY_NAME" >> $GITHUB_OUTPUT echo "GITHUB_COMMIT_NUMBER=$TMP_GITHUB_COMMITS_COUNT" >> $GITHUB_OUTPUT echo "GITHUB_SHA=$(echo ${GITHUB_SHA::8})" >> $GITHUB_OUTPUT echo "GITHUB_RUN_ID=$TMP_GITHUB_COUNT_NUMBER" >> $GITHUB_OUTPUT echo "RELEASE_VERSION=$TMP_RELEASE_VERSION" >> $GITHUB_OUTPUT" 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@v3 - name: Install Go uses: actions/setup-go@v3 with: go-version: ${{ env.GO_VERSION }} - 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 env: GITHUB_TOKEN: ${{ secrets.GHCR_TOKEN }} run: | make test CI_RUN=${CI} - name: Upload codecov result uses: codecov/codecov-action@v1 continue-on-error: true with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos files: coverage.out code_scans: needs: [ prepare ] name: Code scans pipeline runs-on: ubuntu-20.04 steps: - name: Checkout repo uses: actions/checkout@v3 - name: Install Go uses: actions/setup-go@v3 with: go-version: ${{ env.GO_VERSION }} - name: Configure git for private modules run: | 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: ./... create-dummy-release: needs: [ prepare, test, code_scans ] name: Create empty release runs-on: ubuntu-latest steps: - name: Checkout repo uses: actions/checkout@v3 - 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 empty release uses: ncipollo/release-action@v1 with: bodyFile: ./.release_notes name: version ${{ needs.prepare.outputs.RELEASE_VERSION }} token: ${{ secrets.GHCR_TOKEN }} tag: ${{ needs.prepare.outputs.RELEASE_VERSION }} prerelease: ${{ github.ref != 'refs/heads/master' && github.ref != 'refs/heads/main' }} allowUpdates: true build: needs: [ prepare, test, code_scans ] name: Docker image build (regular:multiarch) runs-on: ubuntu-latest steps: - name: Checkout repo uses: actions/checkout@v3 - 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: | if [ -z "${{ needs.prepare.outputs.RELEASE_VERSION }}" ]; then TAGS="${{ needs.prepare.outputs.DOCKER_IMAGE }}:${{ needs.prepare.outputs.GITHUB_SHA }},${{ needs.prepare.outputs.DOCKER_IMAGE }}:latest" else 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" fi echo "TAGS=$TAGS" >> $GITHUB_OUTPUT 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 "LABELS=$LABELS" >> $GITHUB_OUTPUT BUILD_ARGS="BRANCH=$BRANCH" echo "args=$BUILD_ARGS" >> $GITHUB_OUTPUT - 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: false build-binary: needs: [ prepare, test, code_scans, create-dummy-release ] name: Binary compilation and release runs-on: ubuntu-latest strategy: matrix: # build and publish in parallel: linux/386, linux/amd64, linux/arm64, windows/386, windows/amd64, darwin/amd64, darwin/arm64 goos: [linux, windows, darwin] goarch: ["386", amd64, arm64] exclude: - goarch: "386" goos: darwin - goarch: arm64 goos: windows continue-on-error: [true] steps: - name: Checkout code uses: actions/checkout@v3 with: fetch-depth: 0 - name: Install Go uses: actions/setup-go@v3 with: go-version: ${{ env.GO_VERSION }} - name: Compile and release semver uses: wangyoucao577/go-release-action@v1.33 with: github_token: ${{ secrets.GHCR_TOKEN }} goos: ${{ matrix.goos }} goarch: ${{ matrix.goarch }} ldflags: -s -w -X main.PKG_VERSION=${{ needs.prepare.outputs.RELEASE_VERSION }} project_path: . binary_name: semver-gen asset_name: semver-gen-${{ matrix.goos }}-${{ matrix.goarch }} release_name: version ${{ needs.prepare.outputs.RELEASE_VERSION }} release_tag: ${{ needs.prepare.outputs.RELEASE_VERSION }} compress_assets: false retry: 10 overwrite: true pre_command: export GODEBUG=http2client=0 - name: Compile and release v1 uses: wangyoucao577/go-release-action@v1.33 with: github_token: ${{ secrets.GHCR_TOKEN }} goos: ${{ matrix.goos }} goarch: ${{ matrix.goarch }} ldflags: -s -w -X main.PKG_VERSION=${{ needs.prepare.outputs.RELEASE_VERSION }} project_path: . binary_name: semver-gen asset_name: semver-gen-${{ matrix.goos }}-${{ matrix.goarch }} release_name: version v1 release_tag: v1 compress_assets: false retry: 10 overwrite: true pre_command: export GODEBUG=http2client=0