diff --git a/.github/workflows/build-test-publish.yml b/.github/workflows/build-test-publish.yml new file mode 100644 index 0000000..9117948 --- /dev/null +++ b/.github/workflows/build-test-publish.yml @@ -0,0 +1,155 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json +name: Build, Test, Coverage, and Publish + +on: + push: + branches: [main] + pull_request: + branches: [main] + release: + types: [created] + +permissions: + contents: read + +jobs: + test: + name: Run Tests with Coverage and SARIF + runs-on: ubuntu-latest + + permissions: + contents: write + checks: write + pull-requests: write + security-events: write + statuses: write + + steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0 + with: + egress-policy: audit + + - name: Checkout code + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Set up Go + uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5.4.0 + with: + go-version-file: "./go.mod" + cache: true + + - name: Install dependencies + run: go mod tidy + + - name: Run tests + run: go test -json ./... > test-results.json + + - name: Generate coverage report + run: go test -coverprofile=coverage.out ./... + + - name: Check coverage + id: coverage + run: | + coverage="$(go tool cover -func=coverage.out | grep total | awk '{print substr($3, 1, length($3)-1)}')" + echo "total_coverage=$coverage" >> "$GITHUB_ENV" + echo "Coverage: $coverage%" + + - name: Upload test results + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: test-results + path: test-results.json + + - name: Cleanup + run: rm coverage.out + + - name: Fail if coverage is below threshold + run: | + if (( $(echo "$total_coverage < 50" | bc -l) )); then + echo "Coverage ($total_coverage%) is below the threshold (50%)" + exit 1 + fi + + build: + name: Build Binaries + needs: test + runs-on: ubuntu-latest + + permissions: + contents: write + packages: write + + strategy: + matrix: + goos: [linux, darwin, windows] + goarch: [amd64, arm64, arm] + + steps: + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Set up Go + uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5.4.0 + with: + go-version-file: "./go.mod" + + - name: Run go mod tidy + run: go mod tidy + + - name: Build binary for ${{ matrix.goos }}-${{ matrix.goarch }} + run: | + mkdir -p dist + GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }} go build \ + -ldflags "-X main.Version=${{ github.ref_name }}" \ + -o dist/gibidify-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.goos == 'windows' && '.exe' || '' }} \ + . + + - name: Generate SHA256 checksum + run: | + cd dist + for f in gibidify-*; do + sha256sum "$f" > "$f.sha256" + done + + - name: Upload artifact + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: gibidify-${{ matrix.goos }}-${{ matrix.goarch }} + path: dist/* + + docker: + name: Build and Publish Docker Image + if: github.event_name == 'release' + needs: build + runs-on: ubuntu-latest + + permissions: + contents: write + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Download Linux binaries + uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1 + with: + name: gibidify-linux-amd64 + path: . + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0 + + - name: Log in to GitHub Container Registry + run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin + + - name: Build and push multi-arch Docker image + run: | + chmod +x gibidify-linux-amd64 + mv gibidify-linux-amd64 gibidify + docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 \ + --tag ghcr.io/${{ github.repository }}/gibidify:${{ github.ref_name }} \ + --tag ghcr.io/${{ github.repository }}/gibidify:latest \ + --push \ + --squash . diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index c806e38..0000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,84 +0,0 @@ ---- -# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json -name: Build and Publish - -# yamllint disable-line rule:truthy -on: - push: - branches: [main] - pull_request: - branches: [main] - release: - types: [created] - -permissions: read-all - -jobs: - build: - name: Build Binaries - runs-on: ubuntu-latest - - permissions: - contents: write - packages: write - actions: write - - strategy: - matrix: - goos: ["linux", "darwin"] - - steps: - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Set up Go - uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 - with: - go-version-file: "./go.mod" - - - name: Run go mod tidy - shell: bash - run: go mod tidy - - - name: Build binary for ${{ matrix.goos }} - shell: bash - run: | - GOOS=${{ matrix.goos }} GOARCH=amd64 go build \ - -ldflags "-X main.Version=dev-$(date -u +%Y%m%d%H%M)" \ - -o gibidify-${{ matrix.goos }} \ - . - - - name: Upload artifact for ${{ matrix.goos }} - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 - with: - name: gibidify-${{ matrix.goos }} - path: gibidify-${{ matrix.goos }} - - docker: - name: Build and Publish Docker Image - if: github.event_name == 'release' - needs: build - runs-on: ubuntu-latest - - permissions: - packages: write - actions: write - - steps: - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Download Linux binary artifact - uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 - with: - name: gibidify-linux - path: . - - - name: Build Docker image - shell: bash - run: | - cp ./gibidify-linux ./gibidify - chmod +x ./gibidify - docker build -t ghcr.io/${{ github.repository }}/gibidify:${{ github.ref_name }} . diff --git a/.github/workflows/test-coverage-sarif.yml b/.github/workflows/test-coverage-sarif.yml deleted file mode 100644 index 625ead0..0000000 --- a/.github/workflows/test-coverage-sarif.yml +++ /dev/null @@ -1,68 +0,0 @@ ---- -# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json -name: Go Tests with Coverage to SARIF - -# yamllint disable-line rule:truthy -on: - push: - branches: [main] - pull_request: - branches: [main] - -permissions: read-all - -jobs: - test: - runs-on: ubuntu-latest - - permissions: - contents: write - checks: write - pull-requests: write - security-events: write - statuses: write - - steps: - - name: Checkout code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - repository: ivuorinen/gibidify - ref: ${{ github.event.pull_request.head.ref }} - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Set up Go - uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5.4.0 - with: - go-version-file: "./go.mod" - - - name: Install dependencies - shell: bash - run: go mod tidy - - - name: Run tests - shell: bash - run: go test -v ./... - - - name: Generate coverage report - shell: bash - run: go test -coverprofile=coverage.out ./... - - - name: Check coverage - id: coverage - shell: bash - run: | - coverage=$(go tool cover -func=coverage.out | grep total | awk '{print substr($3, 1, length($3)-1)}') - echo "total_coverage=$coverage" >> "$GITHUB_OUTPUT" - echo "Coverage: $coverage%" - - - name: Cleanup - shell: bash - run: rm coverage.out - - - name: Fail if coverage is below threshold - shell: bash - run: | - if (( $(echo "$total_coverage < 50" | bc -l) )); then - echo "Coverage ($total_coverage%) is below the threshold (50%)" - exit 1 - fi