-
Notifications
You must be signed in to change notification settings - Fork 157
Expand file tree
/
Copy pathapi-diff.sh
More file actions
executable file
·171 lines (143 loc) · 5.18 KB
/
api-diff.sh
File metadata and controls
executable file
·171 lines (143 loc) · 5.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#!/bin/bash
# Script to check API diffs using oasdiff
# Usage: ./scripts/api-diff/api-diff.sh [--fail-on-breaking] [filename.yaml]
# Assumes you have Docker installed and the repo is checked out with master branch available
set -e # Exit on error
set -o pipefail # Catch errors in pipes
# Change to repo root
cd "$(dirname "$0")/../.."
# Configuration
DOCKER_IMAGE="${OASDIFF_DOCKER_IMAGE:-tufin/oasdiff:latest}"
BASE_BRANCH="${BASE_BRANCH:-origin/master}"
FAIL_ON_BREAKING=false
TARGET_FILE=""
# Parse arguments
for arg in "$@"; do
if [ "$arg" = "--fail-on-breaking" ]; then
FAIL_ON_BREAKING=true
elif [[ "$arg" == *.yaml ]]; then
TARGET_FILE="$arg"
fi
done
# If --fail-on-breaking not explicitly set, determine based on branch name
if [ "$FAIL_ON_BREAKING" = false ]; then
CURRENT_BRANCH=$(git branch --show-current 2>/dev/null || echo "")
if [[ "$CURRENT_BRANCH" == *breaking* ]]; then
echo "Branch '$CURRENT_BRANCH' contains 'breaking', allowing breaking changes"
FAIL_ON_BREAKING=false
else
echo "Branch '$CURRENT_BRANCH' does not contain 'breaking', failing on breaking changes"
FAIL_ON_BREAKING=true
fi
fi
echo "Starting API diff check..."
# Ensure we're in the repo root
if [ ! -f "xero_accounting.yaml" ]; then
echo "Error: Not in repo root or xero_accounting.yaml not found"
exit 1
fi
# Fetch master if not already done
git fetch "${BASE_BRANCH%%/*}" "${BASE_BRANCH##*/}" 2>/dev/null || echo "Warning: Could not fetch ${BASE_BRANCH}"
# Create temp directory for master branch files (outside repo to avoid overlap with /current mount)
TEMP_DIR=$(mktemp -d)
trap "rm -rf $TEMP_DIR" EXIT
# Get list of xero*.yaml files (excluding any master_*.yaml files)
if [ -n "$TARGET_FILE" ]; then
# Single file specified
if [ ! -f "$TARGET_FILE" ]; then
echo "Error: File '$TARGET_FILE' not found"
exit 1
fi
files="$TARGET_FILE"
echo "Running diff for single file: $TARGET_FILE"
else
# All xero*.yaml files
files=$(ls xero*.yaml 2>/dev/null | grep -v "^master_")
if [ -z "$files" ]; then
echo "No xero*.yaml files found"
exit 1
fi
fi
BREAKING_CHANGES_FOUND=false
FILES_WITH_BREAKING_CHANGES=()
TOTAL_FILES=0
PROCESSED_FILES=0
echo "========================================"
echo "API Diff Summary"
echo "Using Docker image: $DOCKER_IMAGE"
echo "Base branch: $BASE_BRANCH"
echo "========================================"
for file in $files; do
TOTAL_FILES=$((TOTAL_FILES + 1))
echo ""
echo "========== $file =========="
# Get the file from master branch
if ! git show "$BASE_BRANCH:$file" > "$TEMP_DIR/$file" 2>/dev/null; then
echo "ℹ️ New file (does not exist in master branch)"
continue
fi
# Verify the temp file was created
if [ ! -f "$TEMP_DIR/$file" ]; then
echo "❌ Failed to create temp file"
continue
fi
# Note: oasdiff has some non-deterministic behavior in change counts due to
# unordered map iteration in Go. Error counts are consistent, but warning
# counts may vary by ~2-3% between runs. This is a known limitation.
# Run oasdiff changelog
echo "--- Changelog ---"
set +e
CHANGELOG_OUTPUT=$(docker run --rm -v "$(pwd)":/current -v "$TEMP_DIR":/base "$DOCKER_IMAGE" changelog --include-path-params /base/"$file" /current/"$file" 2>&1)
CHANGELOG_EXIT=$?
set -e
echo "$CHANGELOG_OUTPUT"
if [ $CHANGELOG_EXIT -eq 0 ]; then
echo "✓ Changelog generated successfully"
else
echo "⚠ Could not generate changelog (exit code: $CHANGELOG_EXIT)"
fi
# Run breaking changes check
echo ""
echo "--- Breaking changes check ---"
set +e
BREAKING_OUTPUT=$(docker run --rm -v "$(pwd)":/current -v "$TEMP_DIR":/base "$DOCKER_IMAGE" breaking --fail-on ERR --include-path-params /base/"$file" /current/"$file" 2>&1)
BREAKING_EXIT=$?
set -e
echo "$BREAKING_OUTPUT"
if [ $BREAKING_EXIT -eq 0 ]; then
echo "✓ No breaking changes detected"
else
echo "⚠ Breaking changes detected (exit code: $BREAKING_EXIT)"
BREAKING_CHANGES_FOUND=true
FILES_WITH_BREAKING_CHANGES+=("$file")
fi
PROCESSED_FILES=$((PROCESSED_FILES + 1))
done
echo ""
echo "========================================"
echo "API Diff check completed"
echo "Processed: $PROCESSED_FILES/$TOTAL_FILES files"
echo "========================================"
# Summary
if [ "$BREAKING_CHANGES_FOUND" = true ]; then
echo ""
echo "❌ Breaking changes detected in the following files:"
for file in "${FILES_WITH_BREAKING_CHANGES[@]}"; do
echo " - $file"
# Output GitHub Actions annotation
if [ -n "$GITHUB_ACTIONS" ]; then
echo "::warning file=${file}::Breaking changes detected in this API spec file"
fi
done
if [ "$FAIL_ON_BREAKING" = true ]; then
echo ""
echo "Exiting with error due to breaking changes"
exit 1
else
echo ""
echo "Note: Not failing build (use --fail-on-breaking to fail on breaking changes)"
fi
else
echo ""
echo "✓ No breaking changes detected across all files"
fi