diff --git a/.github/workflows/pr-title.yml b/.github/workflows/pr-title.yml new file mode 100644 index 000000000..0055d1a8a --- /dev/null +++ b/.github/workflows/pr-title.yml @@ -0,0 +1,35 @@ +name: PR Title + +on: + pull_request_target: + types: [opened, edited, synchronize] + +permissions: + pull-requests: read + +jobs: + validate: + name: Validate PR Title + runs-on: ubuntu-latest + steps: + - uses: amannn/action-semantic-pull-request@0723387faaf9b38adef4775cd42cfd5155ed6017 # v5.5.3 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + types: | + feat + fix + docs + refactor + test + chore + perf + style + ci + infra + revert + release + requireScope: true + subjectPattern: ^[a-z].+$ + subjectPatternError: | + The subject "{subject}" must start with a lowercase letter. diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml new file mode 100644 index 000000000..41eecdce7 --- /dev/null +++ b/.github/workflows/release-please.yml @@ -0,0 +1,250 @@ +name: Release Please + +on: + push: + branches: [main] + +permissions: + contents: write + issues: write + pull-requests: write + +jobs: + release-please: + name: Release Please + runs-on: ubuntu-latest + outputs: + release_created: ${{ steps.release.outputs.release_created }} + tag_name: ${{ steps.release.outputs.tag_name }} + steps: + - uses: googleapis/release-please-action@16a9c90856f42705d54a6fda1823352bdc62cf38 # v4.4.0 (pin SHA to avoid supply chain attacks) + id: release + with: + token: ${{ secrets.GITHUB_TOKEN }} + config-file: release-please-config.json + manifest-file: .release-please-manifest.json + + prepare-source: + name: Prepare source tarball + needs: release-please + if: needs.release-please.outputs.release_created == 'true' + runs-on: ubuntu-24.04 + steps: + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 (pin SHA to avoid supply chain attacks) + with: + ref: ${{ needs.release-please.outputs.tag_name }} + + - name: Setup Go + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 (pin SHA to avoid supply chain attacks) + with: + go-version: '^1.24.0' + + - name: Prepare source tarball + run: | + TAG="${{ needs.release-please.outputs.tag_name }}" + SRCDIR="croc-${TAG}" + cp -r . "${SRCDIR}" + rm -rf "${SRCDIR}/.git" + cd "${SRCDIR}" && go mod tidy && go mod vendor + cd .. && tar -czvf "croc_${TAG}_src.tar.gz" "${SRCDIR}" + + - name: Upload source artifact + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 (pin SHA to avoid supply chain attacks) + with: + name: source-tarball + path: "*.tar.gz" + + build: + name: Build ${{ matrix.name }} + needs: release-please + if: needs.release-please.outputs.release_created == 'true' + runs-on: ubuntu-24.04 + strategy: + matrix: + include: + # Windows builds + - goos: windows + goarch: amd64 + name: Windows-64bit + ext: .exe + archive: zip + - goos: windows + goarch: "386" + name: Windows-32bit + ext: .exe + archive: zip + - goos: windows + goarch: arm + name: Windows-ARM + ext: .exe + archive: zip + - goos: windows + goarch: arm64 + name: Windows-ARM64 + ext: .exe + archive: zip + + # Linux builds + - goos: linux + goarch: amd64 + name: Linux-64bit + ext: "" + archive: tar.gz + - goos: linux + goarch: "386" + name: Linux-32bit + ext: "" + archive: tar.gz + - goos: linux + goarch: arm + name: Linux-ARM + ext: "" + archive: tar.gz + - goos: linux + goarch: arm + goarm: "5" + name: Linux-ARMv5 + ext: "" + archive: tar.gz + - goos: linux + goarch: arm64 + name: Linux-ARM64 + ext: "" + archive: tar.gz + - goos: linux + goarch: riscv64 + name: Linux-RISCV64 + ext: "" + archive: tar.gz + + # macOS builds + - goos: darwin + goarch: amd64 + name: macOS-64bit + ext: "" + archive: tar.gz + - goos: darwin + goarch: arm64 + name: macOS-ARM64 + ext: "" + archive: tar.gz + + # BSD builds + - goos: dragonfly + goarch: amd64 + name: DragonFlyBSD-64bit + ext: "" + archive: tar.gz + - goos: freebsd + goarch: amd64 + name: FreeBSD-64bit + ext: "" + archive: tar.gz + - goos: freebsd + goarch: arm64 + name: FreeBSD-ARM64 + ext: "" + archive: tar.gz + - goos: netbsd + goarch: "386" + name: NetBSD-32bit + ext: "" + archive: tar.gz + - goos: netbsd + goarch: amd64 + name: NetBSD-64bit + ext: "" + archive: tar.gz + - goos: netbsd + goarch: arm64 + name: NetBSD-ARM64 + ext: "" + archive: tar.gz + - goos: openbsd + goarch: amd64 + name: OpenBSD-64bit + ext: "" + archive: tar.gz + - goos: openbsd + goarch: arm64 + name: OpenBSD-ARM64 + ext: "" + archive: tar.gz + + steps: + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 (pin SHA to avoid supply chain attacks) + with: + ref: ${{ needs.release-please.outputs.tag_name }} + + - name: Setup Go + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 (pin SHA to avoid supply chain attacks) + with: + go-version: '^1.24.0' + + - name: Build binary + env: + CGO_ENABLED: 0 + GOOS: ${{ matrix.goos }} + GOARCH: ${{ matrix.goarch }} + GOARM: ${{ matrix.goarm }} + run: | + case "${{ matrix.goos }}" in + "darwin") + LDFLAGS='-s -extldflags "-sectcreate __TEXT __info_plist Info.plist"' + ;; + "dragonfly"|"freebsd"|"netbsd"|"openbsd") + LDFLAGS="" + ;; + *) + LDFLAGS='-extldflags "-static"' + ;; + esac + + echo "Building for ${{ matrix.goos }}/${{ matrix.goarch }} with LDFLAGS: $LDFLAGS" + go build -ldflags "$LDFLAGS" -o croc${{ matrix.ext }} + + - name: Create archive + run: | + TAG="${{ needs.release-please.outputs.tag_name }}" + if [ "${{ matrix.archive }}" = "zip" ]; then + zip "croc_${TAG}_${{ matrix.name }}.zip" croc${{ matrix.ext }} LICENSE + else + tar -czvf "croc_${TAG}_${{ matrix.name }}.tar.gz" croc${{ matrix.ext }} LICENSE + fi + + - name: Upload build artifact + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 (pin SHA to avoid supply chain attacks) + with: + name: build-${{ matrix.name }} + path: | + *.zip + *.tar.gz + + release: + name: Upload release assets + needs: [release-please, prepare-source, build] + if: needs.release-please.outputs.release_created == 'true' + runs-on: ubuntu-24.04 + steps: + - name: Download all artifacts + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 (pin SHA to avoid supply chain attacks) + with: + merge-multiple: true + + - name: Generate checksums + run: | + TAG="${{ needs.release-please.outputs.tag_name }}" + sha256sum *.zip *.tar.gz > "croc_${TAG}_checksums.txt" + echo "Generated checksums:" + cat "croc_${TAG}_checksums.txt" + + - name: Upload release assets + uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2.2.2 (pin SHA to avoid supply chain attacks) + with: + tag_name: ${{ needs.release-please.outputs.tag_name }} + files: | + *.zip + *.tar.gz + *_checksums.txt diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8f3157884..d36852a4d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,6 +4,10 @@ on: release: types: [created] workflow_dispatch: + inputs: + tag: + description: 'Release tag (e.g. v10.4.3)' + required: true permissions: contents: write @@ -13,21 +17,26 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + ref: ${{ github.event.release.tag_name || inputs.tag }} - name: Setup Go - uses: actions/setup-go@v6 + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: go-version: '^1.24.0' - name: Prepare source tarball run: | - git clone -b ${{ github.event.release.name }} --depth 1 https://github.com/schollz/croc croc-${{ github.event.release.name }} - cd croc-${{ github.event.release.name }} && go mod tidy && go mod vendor - cd .. && tar -czvf croc_${{ github.event.release.name }}_src.tar.gz croc-${{ github.event.release.name }} + TAG="${{ github.event.release.tag_name || inputs.tag }}" + SRCDIR="croc-${TAG}" + cp -r . "${SRCDIR}" + rm -rf "${SRCDIR}/.git" + cd "${SRCDIR}" && go mod tidy && go mod vendor + cd .. && tar -czvf "croc_${TAG}_src.tar.gz" "${SRCDIR}" - name: Upload source artifact - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: source-tarball path: "*.tar.gz" @@ -148,10 +157,12 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + ref: ${{ github.event.release.tag_name || inputs.tag }} - name: Setup Go - uses: actions/setup-go@v6 + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: go-version: '^1.24.0' @@ -180,14 +191,15 @@ jobs: - name: Create archive run: | + TAG="${{ github.event.release.tag_name || inputs.tag }}" if [ "${{ matrix.archive }}" = "zip" ]; then - zip croc_${{ github.event.release.name }}_${{ matrix.name }}.zip croc${{ matrix.ext }} LICENSE + zip "croc_${TAG}_${{ matrix.name }}.zip" croc${{ matrix.ext }} LICENSE else - tar -czvf croc_${{ github.event.release.name }}_${{ matrix.name }}.tar.gz croc${{ matrix.ext }} LICENSE + tar -czvf "croc_${TAG}_${{ matrix.name }}.tar.gz" croc${{ matrix.ext }} LICENSE fi - name: Upload build artifact - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: build-${{ matrix.name }} path: | @@ -197,25 +209,25 @@ jobs: release: needs: [prepare-source, build] runs-on: ubuntu-24.04 - if: github.event_name == 'release' + if: github.event_name == 'release' || github.event_name == 'workflow_dispatch' steps: - name: Download all artifacts - uses: actions/download-artifact@v8 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: merge-multiple: true - name: Generate checksums run: | - # Generate SHA256 checksums for all archives - sha256sum *.zip *.tar.gz > croc_${{ github.event.release.name }}_checksums.txt + TAG="${{ github.event.release.tag_name || inputs.tag }}" + sha256sum *.zip *.tar.gz > "croc_${TAG}_checksums.txt" - # Display the checksums file for verification echo "Generated checksums:" - cat croc_${{ github.event.release.name }}_checksums.txt + cat "croc_${TAG}_checksums.txt" - name: Upload release assets - uses: softprops/action-gh-release@v2 + uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2.2.2 with: + tag_name: ${{ github.event.release.tag_name || inputs.tag }} files: | *.zip *.tar.gz diff --git a/.release-please-manifest.json b/.release-please-manifest.json new file mode 100644 index 000000000..8fbfd3830 --- /dev/null +++ b/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "10.4.2" +} diff --git a/release-please-config.json b/release-please-config.json new file mode 100644 index 000000000..c9d8a8267 --- /dev/null +++ b/release-please-config.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", + "release-type": "go", + "include-v-in-tag": true, + "bootstrap-sha": "1b7e260f61df0e10eca788d3593378233be74bcd", + "packages": { + ".": { + "changelog-path": "CHANGELOG.md" + } + } +}