Skip to content

Commit 7f0667c

Browse files
authored
add homebrew-sync script (#25)
* add homebrew-sync script * updates from feedback
1 parent d8527d8 commit 7f0667c

File tree

3 files changed

+224
-0
lines changed

3 files changed

+224
-0
lines changed

.travis.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ jobs:
1818
- stage: Test
1919
script: make spellcheck
2020
name: Markdown Spellcheck
21+
- stage: Test
22+
script: make homebrew-sync-dry-run
23+
name: Homebrew Sync Dry-Run
2124
- stage: Test
2225
script: make build-binaries
2326
name: Build Binaries

Makefile

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
VERSION ?= $(shell git describe --tags --always --dirty)
22
BIN ?= ec2-instance-selector
33
IMG ?= amazon/amazon-ec2-instance-selector
4+
REPO_FULL_NAME ?= aws/amazon-ec2-instance-selector
45
IMG_TAG ?= ${VERSION}
56
IMG_W_TAG = ${IMG}:${IMG_TAG}
67
DOCKERHUB_USERNAME ?= ""
@@ -12,9 +13,14 @@ MAKEFILE_PATH = $(dir $(realpath -s $(firstword $(MAKEFILE_LIST))))
1213
BUILD_DIR_PATH = ${MAKEFILE_PATH}/build
1314
SUPPORTED_PLATFORMS ?= "windows/amd64,darwin/amd64,linux/amd64,linux/arm64,linux/arm"
1415
SELECTOR_PKG_VERSION_VAR=github.com/aws/amazon-ec2-instance-selector/pkg/selector.versionID
16+
LATEST_RELEASE_TAG=$(shell git tag | tail -1)
17+
PREVIOUS_RELEASE_TAG=$(shell git tag | tail -2 | head -1)
1518

1619
$(shell mkdir -p ${BUILD_DIR_PATH} && touch ${BUILD_DIR_PATH}/_go.mod)
1720

21+
repo-full-name:
22+
@echo ${REPO_FULL_NAME}
23+
1824
compile:
1925
@echo ${MAKEFILE_PATH}
2026
go build -a -ldflags "-X main.versionID=${VERSION} -X ${SELECTOR_PKG_VERSION_VAR}=${VERSION}" -tags="aeis${GOOS}" -o ${BUILD_DIR_PATH}/${BIN} ${MAKEFILE_PATH}/cmd/main.go
@@ -45,6 +51,12 @@ push-docker-images:
4551
version:
4652
@echo ${VERSION}
4753

54+
latest-release-tag:
55+
@echo ${LATEST_RELEASE_TAG}
56+
57+
previous-release-tag:
58+
@echo ${PREVIOUS_RELEASE_TAG}
59+
4860
image:
4961
@echo ${IMG_W_TAG}
5062

@@ -79,6 +91,12 @@ sync-readme-to-dockerhub:
7991
unit-test:
8092
go test -bench=. ${MAKEFILE_PATH}/... -v -coverprofile=coverage.out -covermode=atomic -outputdir=${BUILD_DIR_PATH}
8193

94+
homebrew-sync-dry-run:
95+
${MAKEFILE_PATH}/scripts/sync-to-aws-homebrew-tap -d -b ${BIN} -r ${REPO_FULL_NAME} -p ${SUPPORTED_PLATFORMS} -v ${LATEST_RELEASE_TAG}
96+
97+
homebrew-sync:
98+
${MAKEFILE_PATH}/scripts/sync-to-aws-homebrew-tap -b ${BIN} -r ${GH_REPO} -p ${SUPPORTED_PLATFORMS}
99+
82100
build: compile
83101

84102
release: build-binaries build-docker-images push-docker-images upload-resources-to-github

scripts/sync-to-aws-homebrew-tap

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
5+
BUILD_DIR="${SCRIPTPATH}/../build"
6+
7+
TAP_REPO="aws/homebrew-tap"
8+
TAP_NAME=$(echo ${TAP_REPO} | cut -d'/' -f2)
9+
10+
SYNC_DIR="${BUILD_DIR}/homebrew-sync"
11+
FORK_DIR="${SYNC_DIR}/${TAP_NAME}"
12+
DOWNLOAD_DIR="${BUILD_DIR}/downloads"
13+
BREW_CONFIG_DIR="${BUILD_DIR}/brew-config"
14+
15+
REPO=$(make -s -f "${SCRIPTPATH}/../Makefile" repo-full-name)
16+
BINARY_BASE=""
17+
PLATFORMS=("darwin/amd64" "linux/amd64")
18+
DRY_RUN=0
19+
20+
GH_CLI_VERSION="0.10.1"
21+
GH_CLI_CONFIG_PATH="${HOME}/.config/gh/config.yml"
22+
KERNEL=$(uname -s | tr '[:upper:]' '[:lower:]')
23+
OS="${KERNEL}"
24+
if [[ "${KERNEL}" == "darwin" ]]; then
25+
OS="macOS"
26+
fi
27+
28+
VERSION_REGEX="^v[0-9]+\.[0-9]+\.[0-9]+\$"
29+
VERSION=$(make -s -f "${SCRIPTPATH}/../Makefile" version)
30+
31+
USAGE=$(cat << EOM
32+
Usage: sync-to-aws-homebrew-tap -r <repo> -b <binary-basename> -p <platform_pairs>
33+
Syncs tar.gz\'d binaries to the aws/homebrew-tap
34+
35+
Example: sync-to-aws-homebrew-tap -r "aws/amazon-ec2-instance-selector"
36+
Required:
37+
-b Binary basename (i.e. -b "ec2-instance-selector")
38+
39+
Optional:
40+
-r Github repo to sync to in the form of "org/name" (i.e. -r "aws/amazon-ec2-instance-selector") [DEFAULT: output of \`make repo-full-name\`]
41+
-v VERSION: The application version of the docker image [DEFAULT: output of \`make version\`]
42+
-p Platform pair list (os/architecture) [DEFAULT: linux/amd64]
43+
-d Dry-Run will do all steps except pushing to git and opening the sync PR
44+
EOM
45+
)
46+
47+
# Process our input arguments
48+
while getopts "p:b:r:v:d" opt; do
49+
case ${opt} in
50+
r ) # Github repo
51+
REPO="$OPTARG"
52+
;;
53+
b ) # binary basename
54+
BINARY_BASE="$OPTARG"
55+
;;
56+
p ) # Supported Platforms
57+
IFS=',' read -ra PLATFORMS <<< "$OPTARG"
58+
;;
59+
v ) # App Version
60+
VERSION="$OPTARG"
61+
;;
62+
d ) # Dry Run
63+
DRY_RUN=1
64+
;;
65+
\? )
66+
echo "$USAGE" 1>&2
67+
exit
68+
;;
69+
esac
70+
done
71+
72+
if [[ -z "${BINARY_BASE}" ]]; then
73+
echo "Binary Basename (-b) must be specified"
74+
exit 3
75+
fi
76+
77+
if [[ ! "${VERSION}" =~ $VERSION_REGEX ]]; then
78+
echo "🙈 Not on a current release, so not syncing with tap $TAP_REPO"
79+
exit 3
80+
fi
81+
82+
if [[ -z $(command -v gh) ]] || [[ ! $(gh --version) =~ $GH_CLI_VERSION ]]; then
83+
mkdir -p ${BUILD_DIR}/gh
84+
curl -Lo ${BUILD_DIR}/gh/gh.tar.gz "https://github.com/cli/cli/releases/download/v${GH_CLI_VERSION}/gh_${GH_CLI_VERSION}_${OS}_amd64.tar.gz"
85+
tar -C ${BUILD_DIR}/gh -xvf "${BUILD_DIR}/gh/gh.tar.gz"
86+
export PATH="${BUILD_DIR}/gh/gh_${GH_CLI_VERSION}_${OS}_amd64/bin:$PATH"
87+
if [[ ! $(gh --version) =~ $GH_CLI_VERSION ]]; then
88+
echo "❌ Failed install of github cli"
89+
exit 4
90+
fi
91+
fi
92+
93+
function restore_gh_config() {
94+
mv -f "${GH_CLI_CONFIG_PATH}.bkup" "${GH_CLI_CONFIG_PATH}" || :
95+
}
96+
97+
if [[ -n $(env | grep GITHUB_TOKEN) ]] && [[ -n "${GITHUB_TOKEN}" ]]; then
98+
trap restore_gh_config EXIT INT TERM ERR
99+
cp -f "${HOME}/.config/gh/config.yml" "${HOME}/.config/gh/config.yml.bkup"
100+
cat << EOF > "${HOME}/.config/gh/config.yml"
101+
hosts:
102+
github.com:
103+
oauth_token: ${GITHUB_TOKEN}
104+
user: ${GITHUB_USERNAME}
105+
EOF
106+
fi
107+
108+
VERSION_NUM=$(echo "${VERSION}" | cut -c 2- | tr -d '\n')
109+
110+
function fail() {
111+
echo "❌ Homebrew sync failed"
112+
exit 5
113+
}
114+
115+
trap fail ERR TERM INT
116+
117+
rm -rf "${DOWNLOAD_DIR}" "${SYNC_DIR}" "${BREW_CONFIG_DIR}"
118+
mkdir -p "${DOWNLOAD_DIR}" "${SYNC_DIR}" "${BREW_CONFIG_DIR}"
119+
120+
BASE_ASSET_URL="https://github.com/${REPO}/releases/download/${VERSION}/${BINARY_BASE}"
121+
MAC_HASH=""
122+
LINUX_HASH=""
123+
LINUX_ARM64_HASH=""
124+
125+
function hash_file() {
126+
local file="${1}"
127+
echo "$(openssl dgst -sha256 "${file}" | cut -d' ' -f2 | tr -d '\n')"
128+
}
129+
130+
for os_arch in "${PLATFORMS[@]}"; do
131+
os=$(echo "${os_arch}" | cut -d'/' -f1)
132+
arch=$(echo "${os_arch}" | cut -d'/' -f2)
133+
134+
asset_url="${BASE_ASSET_URL}-${os}-${arch}.tar.gz"
135+
asset_file="${BINARY_BASE}-${os}-${arch}.tar.gz"
136+
asset_file_path="${DOWNLOAD_DIR}/${asset_file}"
137+
138+
curl -Lo "${asset_file_path}" "${asset_url}"
139+
140+
asset_file_size=$(du -k "${asset_file_path}" | cut -f1)
141+
if [[ "${asset_file_size}" -lt 100 ]]; then
142+
## If we cannot download and dry-run is set, build it locally
143+
if [[ "${DRY_RUN}" -eq 1 ]]; then
144+
${SCRIPTPATH}/build-binaries -d -v "${VERSION}" -p "${os_arch}"
145+
cp "${BUILD_DIR}/bin/${asset_file}" ${asset_file_path}
146+
else
147+
echo "❗️${asset_file_path} is empty, skipping"
148+
continue
149+
fi
150+
fi
151+
152+
if [[ "${os}" == "darwin" ]]; then
153+
MAC_HASH=$(hash_file "${asset_file_path}")
154+
elif [[ "${os}" == "linux" && "${arch}" == "amd64" ]]; then
155+
LINUX_HASH=$(hash_file "${asset_file_path}")
156+
elif [[ "${os}" == "linux" && "${arch}" == "arm64" ]]; then
157+
LINUX_ARM64_HASH=$(hash_file "${asset_file_path}")
158+
fi
159+
160+
done
161+
162+
cat << EOM > "${BREW_CONFIG_DIR}/${BINARY_BASE}.json"
163+
{
164+
"name": "${BINARY_BASE}",
165+
"version": "${VERSION_NUM}",
166+
"bin": "${BINARY_BASE}",
167+
"bottle": {
168+
"root_url": "${BASE_ASSET_URL}",
169+
"sha256": {
170+
"sierra": "${MAC_HASH}",
171+
"linux": "${LINUX_HASH}",
172+
"linux_arm": "${LINUX_ARM64_HASH}"
173+
}
174+
}
175+
}
176+
EOM
177+
178+
if [[ "${DRY_RUN}" -eq 0 ]]; then
179+
if [[ -z "${MAC_HASH}" ]] && [[ -z "${LINUX_HASH}" ]] && [[ -z "${LINUX_ARM64_HASH}" ]]; then
180+
echo "❌ No hashes were calculated and dry-run is NOT engaged. Bailing out so we don't open a bad PR to the tap."
181+
exit 4
182+
fi
183+
cd "${SYNC_DIR}"
184+
gh repo fork $TAP_REPO --clone --remote
185+
cd "${FORK_DIR}"
186+
git remote set-url origin https://${GITHUB_USERNAME}:${GITHUB_TOKEN}@github.com/${TAP_REPO}.git
187+
DEFAULT_BRANCH=$(git rev-parse --abbrev-ref HEAD | tr -d '\n')
188+
189+
cp "${BREW_CONFIG_DIR}/${BINARY_BASE}.json" "${FORK_DIR}/bottle-configs/${BINARY_BASE}.json"
190+
191+
## best effort sync of fork
192+
git pull upstream ${DEFAULT_BRANCH} || :
193+
git push -u origin ${DEFAULT_BRANCH} || :
194+
195+
git checkout -b "${BINARY_BASE}-${VERSION}"
196+
git add "bottle-configs/${BINARY_BASE}.json"
197+
git commit -m "${BINARY_BASE} update to version ${VERSION_NUM}"
198+
199+
git push -u origin "${BINARY_BASE}-${VERSION}"
200+
gh pr create --fill
201+
fi
202+
203+
echo "✅ Homebrew sync complete"

0 commit comments

Comments
 (0)