build binary #241
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: build binary | |
| on: | |
| release: | |
| types: [published] | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: "Version tag to build (e.g., 9.0.0)" | |
| required: true | |
| type: string | |
| jobs: | |
| determine_whether_to_run: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| build_arc: ${{ steps.check-build-arc.outputs.run_jobs }} | |
| version: ${{ steps.get-version.outputs.version }} | |
| steps: | |
| - name: Check if Arc binary should be built | |
| id: check-build-arc | |
| env: | |
| INPUT_VERSION: ${{ inputs.version }} | |
| RELEASE_TAG: ${{ github.event.release.tag_name }} | |
| run: | | |
| TAG_NAME="${INPUT_VERSION:-${RELEASE_TAG}}" | |
| echo "Checking tag $TAG_NAME for ARC build" | |
| if echo "$TAG_NAME" | grep -Eq '^([8-9]|[1-9][0-9]+)\.[0-9]+\.[0-9]+$'; then | |
| echo "run_jobs=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "run_jobs=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Get the version from the tag | |
| id: get-version | |
| env: | |
| INPUT_VERSION: ${{ inputs.version }} | |
| RELEASE_TAG: ${{ github.event.release.tag_name }} | |
| run: | | |
| VERSION="${INPUT_VERSION:-${RELEASE_TAG}}" | |
| echo "version=${VERSION}" >> "$GITHUB_OUTPUT" | |
| build-arc: | |
| name: Build ARC binary | |
| needs: determine_whether_to_run | |
| if: needs.determine_whether_to_run.outputs.build_arc == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 | |
| steps: | |
| - name: Checkout Repository | |
| uses: actions/checkout@v2 | |
| # Build AMI zip on AWS host and upload to this release by tag | |
| - name: building binaries for ami | |
| uses: appleboy/[email protected] | |
| env: | |
| VERSION: ${{ needs.determine_whether_to_run.outputs.version }} | |
| PAT_ACCESS_TOKEN: ${{ secrets.PAT_ACCESS_TOKEN }} | |
| with: | |
| host: ${{ secrets.AWS_BUILD_HOST }} | |
| username: ${{ secrets.AWS_BUILD_USERNAME }} | |
| key: ${{ secrets.AWS_BUILD_KEY }} | |
| port: 22 | |
| envs: VERSION,PAT_ACCESS_TOKEN | |
| script: | | |
| set -euo pipefail | |
| export PATH=$PATH:/usr/local/go/bin:/usr/bin | |
| export GOPATH=$HOME/go | |
| # Write build helper script on the remote host | |
| cat > "$HOME/rs_build.sh" <<'EOS' | |
| #!/usr/bin/env bash | |
| # Usage: rs_build.sh <version> <mode> [branch_or_tag] | |
| # mode: ami | cluster | |
| set -euo pipefail | |
| version="${1:?version required}" | |
| mode="${2:-ami}" | |
| branch="${3:-$version}" | |
| # ----- Token resolution ----- | |
| # Use env PAT_ACCESS_TOKEN or ~/.rs_pat if present. | |
| PAT_ACCESS_TOKEN="${PAT_ACCESS_TOKEN:-}" | |
| if [[ -z "${PAT_ACCESS_TOKEN}" && -f "${HOME}/.rs_pat" ]]; then | |
| PAT_ACCESS_TOKEN="$(cat "${HOME}/.rs_pat")" | |
| fi | |
| : "${PAT_ACCESS_TOKEN:?PAT_ACCESS_TOKEN missing (export it or place it in ~/.rs_pat)}" | |
| if [[ "${mode}" != "ami" && "${mode}" != "cluster" ]]; then | |
| echo "mode must be 'ami' or 'cluster'"; exit 1 | |
| fi | |
| # ----- Prereqs ----- | |
| command -v go >/dev/null || { echo "go not found on builder"; exit 1; } | |
| command -v zip >/dev/null || { echo "zip not found on builder"; exit 1; } | |
| command -v curl >/dev/null || { echo "curl not found on builder"; exit 1; } | |
| command -v git >/dev/null || { echo "git not found on builder"; exit 1; } | |
| export GO111MODULE=on | |
| export CGO_ENABLED=1 | |
| export PATH="$PATH:/usr/local/go/bin:/usr/bin" | |
| # ----- Clone & build ----- | |
| rm -rf arc-noss build out || true | |
| echo "Cloning appbaseio-confidential/rs-api-server @ ${branch}" | |
| git clone --depth=1 -b "${branch}" "https://${PAT_ACCESS_TOKEN}@github.com/appbaseio-confidential/rs-api-server" arc-noss | |
| pushd arc-noss >/dev/null | |
| make clean | |
| if [[ "${mode}" == "ami" ]]; then | |
| BILLING=true CLUSTER_BILLING= VERSION="${version}" make | |
| else | |
| BILLING= CLUSTER_BILLING=true VERSION="${version}" make | |
| fi | |
| popd >/dev/null | |
| mkdir -p out | |
| # Zip without the leading arc-noss/ so the archive has build/ and go/ at root | |
| pushd arc-noss >/dev/null | |
| zip -r "../out/arc-linux-${mode}.zip" build go >/dev/null | |
| popd >/dev/null | |
| echo "Packaged out/arc-linux-${mode}.zip (root: build/, go/)" | |
| # ----- Upload to GitHub release (by tag) ----- | |
| owner="appbaseio" | |
| repo="reactivesearch-api" | |
| tag="${version}" | |
| release_json="$(curl -fsSL -H "Authorization: token ${PAT_ACCESS_TOKEN}" \ | |
| "https://api.github.com/repos/${owner}/${repo}/releases/tags/${tag}")" || { | |
| echo "Failed to fetch release for tag ${tag}"; exit 1; } | |
| # First id field is the release id | |
| release_id="$(printf '%s' "${release_json}" | awk -F: '/"id":/{gsub(/[ ,]/,"",$2); print $2; exit}')" || true | |
| if [[ -z "${release_id}" ]]; then | |
| echo "Could not parse release id for tag ${tag}"; exit 1 | |
| fi | |
| asset_path="out/arc-linux-${mode}.zip" | |
| asset_name="$(basename "${asset_path}")" | |
| upload_url="https://uploads.github.com/repos/${owner}/${repo}/releases/${release_id}/assets?name=${asset_name}" | |
| echo "Uploading ${asset_name} to ${owner}/${repo} (release ${tag})..." | |
| http_code="$(curl -sS -w '%{http_code}' -o /tmp/upload_resp.json \ | |
| -X POST -H "Authorization: token ${PAT_ACCESS_TOKEN}" \ | |
| -H "Content-Type: application/octet-stream" \ | |
| --data-binary @"${asset_path}" \ | |
| "${upload_url}")" | |
| if [[ "${http_code}" == "201" ]]; then | |
| echo "Upload successful: ${asset_name}" | |
| elif [[ "${http_code}" == "422" ]]; then | |
| echo "Asset exists; attempting replace…" | |
| if command -v jq >/dev/null 2>&1; then | |
| assets_url="$(printf '%s' "${release_json}" | jq -r '.assets_url')" | |
| assets_json="$(curl -fsSL -H "Authorization: token ${PAT_ACCESS_TOKEN}" "${assets_url}")" | |
| existing_id="$(printf '%s' "${assets_json}" | jq -r ".[] | select(.name==\"${asset_name}\") | .id")" || true | |
| if [[ -n "${existing_id}" && "${existing_id}" != "null" ]]; then | |
| curl -fsSL -X DELETE -H "Authorization: token ${PAT_ACCESS_TOKEN}" \ | |
| "https://api.github.com/repos/${owner}/${repo}/releases/assets/${existing_id}" || true | |
| http_code2="$(curl -sS -w '%{http_code}' -o /tmp/upload_resp2.json \ | |
| -X POST -H "Authorization: token ${PAT_ACCESS_TOKEN}" \ | |
| -H "Content-Type: application/octet-stream" \ | |
| --data-binary @"${asset_path}" \ | |
| "${upload_url}")" | |
| [[ "${http_code2}" == "201" ]] && echo "Re-upload successful" || { echo "Re-upload failed (${http_code2})"; cat /tmp/upload_resp2.json; exit 1; } | |
| else | |
| echo "Could not find existing asset id to delete."; cat /tmp/upload_resp.json; exit 1 | |
| fi | |
| else | |
| echo "jq not available; cannot replace existing asset automatically."; cat /tmp/upload_resp.json; exit 1 | |
| fi | |
| else | |
| echo "Upload failed (${http_code})."; cat /tmp/upload_resp.json; exit 1 | |
| fi | |
| echo "Done." | |
| EOS | |
| chmod +x "$HOME/rs_build.sh" | |
| # Build AMI artifact first so Packer can fetch it | |
| "$HOME/rs_build.sh" "${VERSION}" ami "${VERSION}" | |
| - name: Build AMI | |
| uses: hashicorp/packer-github-actions@master | |
| with: | |
| command: build | |
| target: "./ami.json" | |
| env: | |
| PACKER_LOG: 1 | |
| AWS_ACCESS_KEY: ${{ secrets.AWS_ACCESS_KEY }} | |
| AWS_SECRET_KEY: ${{ secrets.AWS_SECRET_KEY }} | |
| VERSION: ${{ needs.determine_whether_to_run.outputs.version }} | |
| # Reuse the same AWS host to build the cluster zip and upload it | |
| - name: building binaries for cluster (linux/amd64) | |
| uses: appleboy/[email protected] | |
| env: | |
| VERSION: ${{ needs.determine_whether_to_run.outputs.version }} | |
| PAT_ACCESS_TOKEN: ${{ secrets.PAT_ACCESS_TOKEN }} | |
| with: | |
| host: ${{ secrets.AWS_BUILD_HOST }} | |
| username: ${{ secrets.AWS_BUILD_USERNAME }} | |
| key: ${{ secrets.AWS_BUILD_KEY }} | |
| port: 22 | |
| envs: VERSION,PAT_ACCESS_TOKEN | |
| script: | | |
| set -euo pipefail | |
| export PATH=$PATH:/usr/local/go/bin:/usr/bin | |
| export GOPATH=$HOME/go | |
| if [[ ! -x "$HOME/rs_build.sh" ]]; then | |
| echo "Missing build helper; abort."; exit 1 | |
| fi | |
| "$HOME/rs_build.sh" "${VERSION}" cluster "${VERSION}" | |
| send-packer-event-arc: | |
| name: Send Packer Event | |
| needs: build-arc | |
| uses: ./.github/workflows/build_images.yml | |
| with: | |
| # Pass a tag-style ref so the called workflow's regex gate passes on manual runs | |
| ref: "refs/tags/${{ needs.determine_whether_to_run.outputs.version }}" | |
| event_name: new_release | |
| secrets: | |
| token: ${{ secrets.REPO_ACCESS_TOKEN }} | |
| send-docker-event-arc: | |
| name: Send Docker Event | |
| needs: [build-arc, determine_whether_to_run] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Send repo dispatch | |
| uses: peter-evans/repository-dispatch@v2 | |
| with: | |
| token: ${{ secrets.REPO_ACCESS_TOKEN }} | |
| repository: appbaseio-confidential/rs-api-server | |
| event-type: publish_docker | |
| client-payload: '{"version": "${{ needs.determine_whether_to_run.outputs.version }}" }' |