Skip to content

build binary

build binary #241

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 }}" }'