diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..9b237c2 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,101 @@ +name: Release + +# A pushed v* tag makes this workflow build every desktop target, run the +# end-to-end suites and attach the binaries to the matching GitHub release. +# workflow_dispatch lets an existing tag be rebuilt without moving it. + +on: + push: + tags: + - "v*" + workflow_dispatch: + inputs: + tag: + description: "Tag to build and publish (for example v1.0.1)" + required: true + type: string + +permissions: + contents: write + +concurrency: + group: release-${{ github.ref }} + cancel-in-progress: false + +jobs: + test: + name: End-to-end tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache: true + + - name: golink suite + run: ./smoketest/run.sh + + - name: goscp suite + run: ./smoketest/run-goscp.sh + + release: + name: Build and publish + needs: test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache: true + + - name: Resolve tag + id: tag + env: + DISPATCH_TAG: ${{ inputs.tag }} + PUSHED_TAG: ${{ github.ref_name }} + run: | + set -euo pipefail + tag="${DISPATCH_TAG:-$PUSHED_TAG}" + echo "value=$tag" >> "$GITHUB_OUTPUT" + echo "building $tag" + + - name: Build every target + env: + TAG: ${{ steps.tag.outputs.value }} + run: | + set -euo pipefail + VERSION="${TAG#v}" ./build.sh + + - name: Verify the binaries + env: + TAG: ${{ steps.tag.outputs.value }} + run: | + set -euo pipefail + want="${TAG#v}" + for program in golink goscp; do + got="$(./dist/$program -version | awk '{print $2}')" + echo "$program: $got" + [ "$got" = "$want" ] || { echo "version mismatch: want $want, got $got" >&2; exit 1; } + done + sha256sum -c dist/SHA256SUMS + + - name: Publish to the release + env: + GH_TOKEN: ${{ github.token }} + TAG: ${{ steps.tag.outputs.value }} + run: | + set -euo pipefail + if gh release view "$TAG" >/dev/null 2>&1; then + echo "release $TAG already exists, replacing assets" + else + gh release create "$TAG" \ + --title "sshtools $TAG" \ + --generate-notes \ + --verify-tag + fi + gh release upload "$TAG" dist/golink_* dist/goscp_* dist/SHA256SUMS --clobber + gh release view "$TAG"