name: Release # Builds release artifacts when a version tag (v*) is pushed: # - cross-compiled CLI + server binaries attached to the Gitea release # - version-tagged docker images for the CLI and web server # The owner usually creates the Gitea release by hand with notes; this # workflow attaches assets to it (creating a bare release only when none # exists) and skips assets that are already attached, so re-runs are safe. on: push: tags: ["v*"] jobs: binaries: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: go-version-file: 'go.mod' cache: true - name: Build release binaries env: GOTOOLCHAIN: local run: | set -euo pipefail TAG="${GITHUB_REF_NAME}" mkdir -p dist for target in linux/amd64 linux/arm64 darwin/amd64 darwin/arm64 windows/amd64; do GOOS="${target%/*}" GOARCH="${target#*/}" EXT="" [ "$GOOS" = "windows" ] && EXT=".exe" OUT="dist/${GOOS}_${GOARCH}" mkdir -p "$OUT" CGO_ENABLED=0 GOOS="$GOOS" GOARCH="$GOARCH" \ go build -trimpath -ldflags "-s -w -X main.version=${TAG}" \ -o "${OUT}/exploredns${EXT}" ./cmd/exploredns CGO_ENABLED=0 GOOS="$GOOS" GOARCH="$GOARCH" \ go build -trimpath -ldflags "-s -w -X main.version=${TAG}" \ -o "${OUT}/exploredns-server${EXT}" ./cmd/server if [ "$GOOS" = "windows" ]; then (cd "$OUT" && zip -q "../exploredns_${TAG}_${GOOS}_${GOARCH}.zip" exploredns.exe exploredns-server.exe) else tar -czf "dist/exploredns_${TAG}_${GOOS}_${GOARCH}.tar.gz" -C "$OUT" exploredns exploredns-server fi rm -rf "$OUT" done (cd dist && sha256sum -- * > SHA256SUMS) ls -l dist - name: Attach assets to Gitea release env: TOKEN: ${{ secrets.GITHUB_TOKEN }} API: ${{ github.server_url }}/api/v1 REPO: ${{ github.repository }} run: | set -euo pipefail TAG="${GITHUB_REF_NAME}" AUTH="Authorization: token ${TOKEN}" # Look up the release for this tag; create a bare one only when # none exists (the owner writes release notes by hand). STATUS=$(curl -sS -o release.json -w '%{http_code}' -H "$AUTH" \ "${API}/repos/${REPO}/releases/tags/${TAG}") if [ "$STATUS" = "404" ]; then curl -sS -f -o release.json -H "$AUTH" -H 'Content-Type: application/json' \ -d "{\"tag_name\":\"${TAG}\",\"name\":\"${TAG}\"}" \ "${API}/repos/${REPO}/releases" elif [ "$STATUS" != "200" ]; then echo "release lookup failed with HTTP ${STATUS}" >&2 cat release.json >&2 exit 1 fi RELEASE_ID=$(jq -r '.id' release.json) echo "release id: ${RELEASE_ID}" # Existing asset names, so re-runs skip instead of failing. curl -sS -f -H "$AUTH" \ "${API}/repos/${REPO}/releases/${RELEASE_ID}/assets" \ | jq -r '.[].name' > existing.txt for f in dist/*; do NAME=$(basename "$f") if grep -Fxq "$NAME" existing.txt; then echo "skip ${NAME} (already attached)" continue fi echo "upload ${NAME}" curl -sS -f -o /dev/null -H "$AUTH" \ -F "attachment=@${f}" \ "${API}/repos/${REPO}/releases/${RELEASE_ID}/assets?name=${NAME}" done docker: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Log in to registry uses: docker/login-action@v3 with: registry: gitea.hansenits.com.au username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Build and push CLI image uses: docker/build-push-action@v6 with: context: . file: Dockerfile.cli push: true build-args: | VERSION=${{ github.ref_name }} tags: | gitea.hansenits.com.au/hits/exploredns-cli:latest gitea.hansenits.com.au/hits/exploredns-cli:${{ github.ref_name }} - name: Build and push web image uses: docker/build-push-action@v6 with: context: . file: Dockerfile.web push: true build-args: | VERSION=${{ github.ref_name }} tags: | gitea.hansenits.com.au/hits/exploredns-web:latest gitea.hansenits.com.au/hits/exploredns-web:${{ github.ref_name }}