name: CI/CD Pipeline on: push: branches: - main - develop tags: - 'v*' pull_request: branches: - main jobs: lint: name: Lint runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Go uses: actions/setup-go@v5 with: go-version: '1.21' - name: Run golangci-lint uses: golangci/golangci-lint-action@v4 with: version: latest args: --timeout=5m - name: Run go fmt check run: | if [ -n "$(gofmt -l .)" ]; then echo "Code is not formatted. Run 'go fmt ./...'" gofmt -l . exit 1 fi - name: Run go vet run: go vet ./... test: name: Test runs-on: ubuntu-latest needs: lint steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Go uses: actions/setup-go@v5 with: go-version: '1.21' - name: Run tests run: go test -v -race -coverprofile=coverage.out ./... - name: Generate coverage report run: go tool cover -html=coverage.out -o coverage.html - name: Upload coverage uses: actions/upload-artifact@v4 with: name: coverage-report path: | coverage.out coverage.html build: name: Build runs-on: ubuntu-latest needs: test strategy: matrix: include: # Linux builds - goos: linux goarch: amd64 output: linkbeam-linux-amd64 - goos: linux goarch: 386 output: linkbeam-linux-386 - goos: linux goarch: arm64 output: linkbeam-linux-arm64 - goos: linux goarch: arm goarm: 7 output: linkbeam-linux-armv7 # Windows builds - goos: windows goarch: amd64 output: linkbeam-windows-amd64.exe - goos: windows goarch: 386 output: linkbeam-windows-386.exe - goos: windows goarch: arm64 output: linkbeam-windows-arm64.exe # macOS builds - goos: darwin goarch: amd64 output: linkbeam-darwin-amd64 - goos: darwin goarch: arm64 output: linkbeam-darwin-arm64 steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Go uses: actions/setup-go@v5 with: go-version: '1.21' - name: Build binary env: GOOS: ${{ matrix.goos }} GOARCH: ${{ matrix.goarch }} GOARM: ${{ matrix.goarm }} run: | go build -o dist/${{ matrix.output }} \ -ldflags="-s -w -X main.Version=${{ github.ref_name }} -X main.Commit=${{ github.sha }}" \ ./cmd/linkbeam - name: Upload artifact uses: actions/upload-artifact@v4 with: name: ${{ matrix.output }} path: dist/${{ matrix.output }} docker: name: Build Docker Image runs-on: ubuntu-latest needs: test steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Extract metadata id: meta uses: docker/metadata-action@v5 with: images: | gitea.example.com/${{ github.repository }} tags: | type=ref,event=branch type=ref,event=pr type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=sha - name: Build Docker image uses: docker/build-push-action@v5 with: context: . platforms: linux/amd64,linux/arm64,linux/arm/v7 push: false tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max - name: Save Docker image if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') run: | docker save -o linkbeam-docker-image.tar ${{ steps.meta.outputs.tags }} - name: Upload Docker image artifact if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') uses: actions/upload-artifact@v4 with: name: docker-image path: linkbeam-docker-image.tar release: name: Create Release runs-on: ubuntu-latest needs: [build, docker] if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') steps: - name: Checkout code uses: actions/checkout@v4 - name: Download all artifacts uses: actions/download-artifact@v4 with: path: release-artifacts - name: Create checksums run: | cd release-artifacts find . -type f -name "linkbeam-*" -exec sha256sum {} \; > checksums.txt - name: Create release uses: actions/create-release@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: ${{ github.ref_name }} release_name: Release ${{ github.ref_name }} draft: false prerelease: false - name: Upload release assets uses: softprops/action-gh-release@v1 with: files: | release-artifacts/**/* release-artifacts/checksums.txt