Skip to content

Commit 7029cc4

Browse files
committed
Merge branch 'main' into feat/jjSupport
2 parents dfa6432 + d6708ff commit 7029cc4

10 files changed

Lines changed: 184 additions & 238 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 }}

.github/workflows/tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ name: Go-Tests
55

66
on:
77
push:
8-
branches: [ "main", "dev" ]
8+
branches: [ "main" ]
99
pull_request:
10-
branches: [ "main", "dev" ]
10+
branches: [ "main", "feat/jjSupport" ]
1111
workflow_dispatch:
1212

1313
jobs:

AGENTS.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ RepoScan is a Go CLI tool that scans filesystems for Git repositories and report
1313
# Build the main binary
1414
go build -o reposcan .
1515

16-
# Install to $GOPATH/bin
17-
go install github.com/mabd-dev/reposcan@latest
16+
# Install
17+
curl -fsSL https://raw.githubusercontent.com/mabd-dev/reposcan/main/install.sh | sh
1818
```
1919

2020
### Testing

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ All notable changes to this project will be documented in this file.
66
## Unreleased
77

88

9+
## [1.3.8] - 2026-04-27
10+
11+
### Added
12+
13+
- Feat/release workflow and install.sh by @AnthonyGeorgeAZ in [#30](https://github.com/mabd-dev/reposcan/pull/30)
14+
- CHANGELOG.md added by @vgauraha62 in [#26](https://github.com/mabd-dev/reposcan/pull/26)
15+
- feat(analytics): add Analytics interface with Mixpanel and stdout backends by @mvanhorn in [#27](https://github.com/mabd-dev/reposcan/pull/27)
16+
917
### 🐛 Bug Fixes
1018

1119
- fix: hide redundant remote name in state column by @mvanhorn in [#23](https://github.com/mabd-dev/reposcan/pull/23)

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@ https://github.com/user-attachments/assets/1c8370c6-3b94-4490-bc96-fc179ef14f1d
3333
## 📦 Installation
3434

3535
### Go install (latest)
36+
3637
```sh
3738
go install github.com/mabd-dev/reposcan@latest
3839
```
3940

40-
Make sure $GOPATH/bin (or $HOME/go/bin) is in your $PATH.
41+
Make sure # $GOPATH/bin (or $HOME/go/bin) is in your $PATH
42+
4143

4244
### From source
4345
```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."

internal/render/stdout/constants.go

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,6 @@ import (
44
"github.com/fatih/color"
55
)
66

7-
const (
8-
RepoW = 24
9-
VCSW = 5
10-
BranchW = 30
11-
UncommW = 3
12-
AheadW = 3
13-
BehindW = 3
14-
RemoteStateW = 40
15-
)
16-
177
var (
188
BoldS = color.New(color.Bold).SprintfFunc()
199
DimS = color.New(color.Faint).SprintfFunc()

internal/render/stdout/scanReport.go

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -22,24 +22,6 @@ func RenderScanReportAsJson(r report.ScanReport) error {
2222
return nil
2323
}
2424

25-
// RenderScanReportAsTable prints a human-readable table view of the ScanReport
26-
// to stdout. The Path column is printed last and not truncated.
27-
func RenderScanReportAsTable(r report.ScanReport) {
28-
totalRepos := len(r.RepoStates)
29-
dirtyRepos := r.DirtyReposCount()
30-
31-
Warnings(r.Warnings)
32-
renderReportHeader(r, totalRepos, dirtyRepos)
33-
34-
if len(r.RepoStates) > 0 {
35-
RenderReposTable(r)
36-
}
37-
38-
if dirtyRepos > 0 {
39-
renderDirtyReposDetails(r)
40-
}
41-
}
42-
4325
func renderReportHeader(r report.ScanReport, totalRepos int, dirtyRepos int) {
4426
fmt.Printf("\n\n")
4527
fmt.Printf("%s\n", BoldS("Repo Scan Report"))
@@ -53,34 +35,6 @@ func renderReportHeader(r report.ScanReport, totalRepos int, dirtyRepos int) {
5335
}
5436
}
5537

56-
func renderDirtyReposDetails(r report.ScanReport) {
57-
fmt.Printf("\n%s\n", CyanBold("Details:"))
58-
for _, rs := range r.RepoStates {
59-
outgoingCommits := rs.OutgoingCommits()
60-
if len(rs.UncommitedFiles) == 0 && len(outgoingCommits) == 0 {
61-
continue
62-
}
63-
fmt.Printf("\n%s %s\n%s %s\n",
64-
MagBold("Repo:"), rs.Repo,
65-
MagBold("Path:"), rs.Path,
66-
)
67-
68-
if len(rs.UncommitedFiles) > 0 {
69-
fmt.Printf("%s\n", MagBold("File Changes:"))
70-
for _, f := range rs.UncommitedFiles {
71-
fmt.Printf(" %s\n", GrayS("- %s", f))
72-
}
73-
}
74-
75-
if len(outgoingCommits) > 0 {
76-
fmt.Printf("%s\n", MagBold("Outgoing Commits:"))
77-
for _, commit := range outgoingCommits {
78-
fmt.Printf(" %s\n", GrayS("- %s", commit))
79-
}
80-
}
81-
}
82-
}
83-
8438
// truncateRunes truncates to at most n visible runes (avoids breaking alignment with multibyte chars)
8539
func truncateRunes(s string, n int) string {
8640
if n <= 0 {

0 commit comments

Comments
 (0)