Skip to content

Commit bedecbf

Browse files
authored
Merge pull request #30 from AnthonyGeorgeAZ/feat/release-workflow-and-install
Feat/release workflow and install
2 parents c315676 + 737abda commit bedecbf

3 files changed

Lines changed: 175 additions & 18 deletions

File tree

.github/workflows/release.yml

Lines changed: 59 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,16 @@ on:
66
- 'v*' # triggers on version tags like v0.1.0, v1.2.3
77

88
permissions:
9-
contents: write
9+
contents: write
1010

1111
jobs:
12+
# ── 1. Create the GitHub release object first ─────────────────────────────
1213
release:
1314
runs-on: ubuntu-latest
14-
1515
steps:
1616
- name: Checkout Code
1717
uses: actions/checkout@v4
1818

19-
- name: Install Linux dependencies
20-
run: |
21-
sudo apt update
22-
sudo apt install -y libx11-dev
23-
2419
- name: Set up Go
2520
uses: actions/setup-go@v4
2621
with:
@@ -29,14 +24,6 @@ jobs:
2924
- name: Download Dependencies
3025
run: go mod tidy
3126

32-
- name: Build Binary
33-
run: |
34-
echo "Building reposcan ${VERSION} ..."
35-
go build -o reposcan .
36-
37-
- name: Verify Version
38-
run: ./reposcan version
39-
4027
- name: Trigger pkg.go.dev indexing
4128
run: |
4229
REPO="${{ github.repository }}"
@@ -64,4 +51,61 @@ jobs:
6451
body_path: RELEASE_NOTES.md
6552
generate_release_notes: false
6653

54+
# ── 2. Build binaries for each platform and attach to the release ─────────
55+
build:
56+
needs: release
57+
strategy:
58+
matrix:
59+
include:
60+
- os: linux
61+
arch: amd64
62+
runner: ubuntu-latest
63+
- os: darwin
64+
arch: amd64
65+
runner: macos-latest
66+
- os: darwin
67+
arch: arm64
68+
runner: macos-latest
69+
70+
runs-on: ${{ matrix.runner }}
71+
72+
steps:
73+
- name: Checkout Code
74+
uses: actions/checkout@v4
75+
76+
- name: Install Linux dependencies
77+
if: matrix.os == 'linux'
78+
run: |
79+
sudo apt update
80+
sudo apt install -y xvfb libx11-dev x11-utils
81+
82+
- name: Set up Go
83+
uses: actions/setup-go@v4
84+
with:
85+
go-version: '1.24.x'
86+
87+
- name: Download Dependencies
88+
run: go mod tidy
6789

90+
- name: Build Binary
91+
env:
92+
GOOS: ${{ matrix.os }}
93+
GOARCH: ${{ matrix.arch }}
94+
CGO_ENABLED: 1
95+
run: |
96+
ASSET_NAME="reposcan-${{ github.ref_name }}-${{ matrix.os }}-${{ matrix.arch }}"
97+
echo "Building $ASSET_NAME ..."
98+
go build \
99+
-ldflags "-X github.com/mabd-dev/reposcan/cmd/reposcan.mixpanelToken=${{ secrets.MIXPANEL_TOKEN }}" \
100+
-o "$ASSET_NAME" \
101+
.
102+
103+
- name: Verify Binary
104+
run: ./reposcan-${{ github.ref_name }}-${{ matrix.os }}-${{ matrix.arch }} version
105+
106+
- name: Upload Binary to Release
107+
uses: softprops/action-gh-release@v2
108+
with:
109+
tag_name: ${{ github.ref_name }}
110+
token: ${{ secrets.GITHUB_TOKEN }}
111+
files: reposcan-${{ github.ref_name }}-${{ matrix.os }}-${{ matrix.arch }}

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,15 @@ https://github.com/user-attachments/assets/1c8370c6-3b94-4490-bc96-fc179ef14f1d
3232

3333
## 📦 Installation
3434

35-
### Go install (latest)
35+
### Install script (recommended)
36+
37+
The easiest way to install `reposcan`. Detects your OS and architecture automatically and installs the latest release binary into a directory on your `$PATH`:
38+
3639
```sh
37-
go install github.com/mabd-dev/reposcan@latest
40+
curl -fsSL https://raw.githubusercontent.com/mabd-dev/reposcan/main/install.sh | sh
3841
```
3942

40-
Make sure $GOPATH/bin (or $HOME/go/bin) is in your $PATH.
43+
Supports **linux/amd64**, **darwin/amd64**, and **darwin/arm64**.
4144

4245
### From source
4346
```sh

install.sh

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
#!/bin/sh
2+
set -e
3+
4+
REPO="mabd-dev/reposcan"
5+
BINARY_NAME="reposcan"
6+
7+
# ── 1. Detect OS ────────────────────────────────────────────────────────────
8+
OS="$(uname -s)"
9+
case "$OS" in
10+
Linux) OS="linux" ;;
11+
Darwin) OS="darwin" ;;
12+
*)
13+
echo "error: unsupported operating system: $OS" >&2
14+
echo " supported: linux, darwin" >&2
15+
exit 1
16+
;;
17+
esac
18+
19+
# ── 2. Detect Arch ──────────────────────────────────────────────────────────
20+
ARCH="$(uname -m)"
21+
case "$ARCH" in
22+
x86_64) ARCH="amd64" ;;
23+
arm64|aarch64) ARCH="arm64" ;;
24+
*)
25+
echo "error: unsupported architecture: $ARCH" >&2
26+
echo " supported: amd64, arm64 (darwin only)" >&2
27+
exit 1
28+
;;
29+
esac
30+
31+
# ── 3. Guard unsupported combos ─────────────────────────────────────────────
32+
if [ "$OS" = "linux" ] && [ "$ARCH" = "arm64" ]; then
33+
echo "error: linux/arm64 is not supported yet." >&2
34+
exit 1
35+
fi
36+
37+
# ── 4. Fetch latest release version from GitHub API ─────────────────────────
38+
echo "Fetching latest release..."
39+
LATEST_URL="https://api.github.com/repos/${REPO}/releases/latest"
40+
41+
if command -v curl >/dev/null 2>&1; then
42+
VERSION="$(curl -fsSL "$LATEST_URL" | grep '"tag_name"' | sed 's/.*"tag_name": *"\([^"]*\)".*/\1/')"
43+
elif command -v wget >/dev/null 2>&1; then
44+
VERSION="$(wget -qO- "$LATEST_URL" | grep '"tag_name"' | sed 's/.*"tag_name": *"\([^"]*\)".*/\1/')"
45+
else
46+
echo "error: curl or wget is required to install reposcan." >&2
47+
exit 1
48+
fi
49+
50+
if [ -z "$VERSION" ]; then
51+
echo "error: could not determine the latest release version." >&2
52+
exit 1
53+
fi
54+
55+
echo "Latest version: $VERSION"
56+
57+
# ── 5. Build download URL ────────────────────────────────────────────────────
58+
ASSET="${BINARY_NAME}-${VERSION}-${OS}-${ARCH}"
59+
DOWNLOAD_URL="https://github.com/${REPO}/releases/download/${VERSION}/${ASSET}"
60+
61+
echo "Downloading $ASSET..."
62+
63+
TMP_DIR="$(mktemp -d)"
64+
TMP_BIN="${TMP_DIR}/${BINARY_NAME}"
65+
trap 'rm -rf "$TMP_DIR"' EXIT
66+
67+
if command -v curl >/dev/null 2>&1; then
68+
curl -fsSL "$DOWNLOAD_URL" -o "$TMP_BIN"
69+
else
70+
wget -qO "$TMP_BIN" "$DOWNLOAD_URL"
71+
fi
72+
73+
chmod +x "$TMP_BIN"
74+
75+
# ── 6. Find a writable directory on $PATH ────────────────────────────────────
76+
find_install_dir() {
77+
# Prefer ~/.local/bin (no sudo needed), then /usr/local/bin
78+
CANDIDATES="$HOME/.local/bin /usr/local/bin /usr/bin"
79+
for DIR in $CANDIDATES; do
80+
if echo ":$PATH:" | grep -q ":${DIR}:" && [ -w "$DIR" ]; then
81+
echo "$DIR"
82+
return
83+
fi
84+
done
85+
86+
# ~/.local/bin is on PATH but doesn't exist yet — create it
87+
LOCAL_BIN="$HOME/.local/bin"
88+
if echo "$PATH" | grep -q "$LOCAL_BIN"; then
89+
mkdir -p "$LOCAL_BIN"
90+
echo "$LOCAL_BIN"
91+
return
92+
fi
93+
94+
echo ""
95+
}
96+
97+
INSTALL_DIR="$(find_install_dir)"
98+
99+
if [ -z "$INSTALL_DIR" ]; then
100+
echo "error: could not find a writable directory on your \$PATH." >&2
101+
echo " Add ~/.local/bin to your PATH and re-run, or install manually:" >&2
102+
echo " sudo mv $TMP_BIN /usr/local/bin/${BINARY_NAME}" >&2
103+
exit 1
104+
fi
105+
106+
mv "$TMP_BIN" "${INSTALL_DIR}/${BINARY_NAME}"
107+
108+
echo ""
109+
echo "reposcan $VERSION installed to ${INSTALL_DIR}/${BINARY_NAME}"
110+
echo "Run 'reposcan --help' to get started."

0 commit comments

Comments
 (0)