Skip to content

Commit f039584

Browse files
committed
feat: try local apidiff
1 parent bad507a commit f039584

File tree

2 files changed

+122
-0
lines changed

2 files changed

+122
-0
lines changed

.github/workflows/api-diff.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,24 @@ jobs:
2323
- uses: joelanford/go-apidiff@60c4206be8f84348ebda2a3e0c3ac9cb54b8f685 # v0.8.3
2424
with:
2525
version: "v0.8.3"
26+
27+
analyze-apidiff:
28+
permissions:
29+
pull-requests: write
30+
contents: read
31+
runs-on: ubuntu-latest
32+
steps:
33+
- name: Checkout the repository
34+
uses: actions/checkout@v4
35+
with:
36+
fetch-depth: 0
37+
38+
- name: Set up Go
39+
uses: ./.github/actions/setup-go
40+
with:
41+
go-version-file: "go.mod"
42+
only-modules: "true"
43+
44+
- name: Run script/apidiff.sh
45+
run: |
46+
./script/apidiff.sh

script/apidiff.sh

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
# script/apidiff.sh
5+
# Compare API of only modified Go packages between PR HEAD and default branch using apidiff.
6+
# Usage: ./script/apidiff.sh
7+
8+
# Ensure apidiff is installed
9+
if ! command -v apidiff &> /dev/null; then
10+
echo "apidiff not found"
11+
exit 1
12+
fi
13+
14+
# Locate repository root
15+
repo_root=$(git rev-parse --show-toplevel)
16+
cd "$repo_root"
17+
18+
echo "Repository root: $repo_root"
19+
20+
# Determine default branch (e.g. main or master)
21+
default_branch=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||' || echo "main")
22+
echo "Default branch: $default_branch"
23+
24+
# Fetch latest origin
25+
git fetch origin "$default_branch"
26+
27+
# Determine modified directories containing Go files
28+
mapfile -t changed_dirs < <(git diff --name-only "origin/$default_branch...HEAD" | grep '\.go$' | xargs -n1 dirname | sort -u)
29+
if [ ${#changed_dirs[@]} -eq 0 ]; then
30+
echo "No modified Go files detected relative to origin/$default_branch. Exiting."
31+
exit 0
32+
fi
33+
34+
echo "Modified directories: ${changed_dirs[*]}"
35+
36+
# Create temporary workspace
37+
tmp_dir=$(mktemp -d)
38+
trap 'rm -rf "$tmp_dir"' EXIT
39+
40+
# Add worktrees for default branch and PR HEAD
41+
git worktree add "$tmp_dir/base" "origin/$default_branch"
42+
git worktree add "$tmp_dir/head" HEAD
43+
44+
# Resolve import paths for changed directories using head worktree
45+
declare -a pkgs
46+
for dir in "${changed_dirs[@]}"; do
47+
pkg_path=$(cd "$tmp_dir/head" && go list "./$dir")
48+
pkgs+=("$pkg_path")
49+
done
50+
# Deduplicate
51+
mapfile -t pkgs < <(printf '%s
52+
' "${pkgs[@]}" | sort -u)
53+
54+
echo "Packages to compare: ${pkgs[*]}"
55+
56+
# Prepare export directories
57+
exports_dir="$tmp_dir/exports"
58+
base_exports="$exports_dir/base"
59+
head_exports="$exports_dir/head"
60+
mkdir -p "$base_exports" "$head_exports"
61+
62+
# Generate exports for specified packages
63+
generate_pkg_exports() {
64+
local tree_path=$1 dest_dir=$2
65+
pushd "$tree_path" > /dev/null
66+
for pkg in "${pkgs[@]}"; do
67+
local rel_name=${pkg//\//_}.export
68+
echo "Writing export for $pkg -> $dest_dir/$rel_name"
69+
apidiff -w "$dest_dir/$rel_name" "$pkg"
70+
done
71+
popd > /dev/null
72+
}
73+
74+
# Run exports
75+
generate_pkg_exports "$tmp_dir/base" "$base_exports"
76+
generate_pkg_exports "$tmp_dir/head" "$head_exports"
77+
78+
# Compare exports for breaking changes
79+
echo -e "\nComparing API for breaking changes..."
80+
broken=false
81+
for pkg in "${pkgs[@]}"; do
82+
file=${pkg//\//_}.export
83+
base_file="$base_exports/$file"
84+
head_file="$head_exports/$file"
85+
echo -e "\nChecking $pkg"
86+
if ! apidiff "$base_file" "$head_file"; then
87+
broken=true
88+
fi
89+
done
90+
91+
# Cleanup worktrees
92+
git worktree remove "$tmp_dir/base" --force
93+
git worktree remove "$tmp_dir/head" --force
94+
95+
# Exit status based on breakages
96+
if [[ "$broken" == true ]]; then
97+
echo -e "\nBreaking API changes detected."
98+
exit 1
99+
else
100+
echo -e "\nNo breaking API changes detected."
101+
fi

0 commit comments

Comments
 (0)