Skip to content

Commit a2444f0

Browse files
authored
Merge pull request #13 from swade1987/merge-branch
fix: compare BASE with merged state instead of HEAD directly
2 parents 183b7e5 + 922933c commit a2444f0

File tree

4 files changed

+58
-21
lines changed

4 files changed

+58
-21
lines changed

Dockerfile

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
FROM alpine:3.21.2
1+
FROM alpine:3.21.3
22

33
RUN apk update && apk --no-cache add bash curl git
44

55
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
66

7-
ARG KUSTOMIZE=5.4.3
7+
ARG KUSTOMIZE=5.6.0
88
RUN curl -sL https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2Fv${KUSTOMIZE}/kustomize_v${KUSTOMIZE}_linux_amd64.tar.gz | \
99
tar xz && mv kustomize /usr/local/bin/kustomize
1010

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ build:
1616
docker buildx build --build-arg BUILDPLATFORM=$(BUILDPLATFORM) --build-arg TARGETARCH=$(GOARCH) -t local/$(PROJNAME) .
1717

1818
scan: build
19-
trivy --light -s "UNKNOWN,MEDIUM,HIGH,CRITICAL" --exit-code 1 local/$(PROJNAME)
19+
trivy image -s "UNKNOWN,MEDIUM,HIGH,CRITICAL" --exit-code 1 local/$(PROJNAME)

README.md

+12-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ Managing Kubernetes configurations across multiple environments and PRs can be c
1313
## Features
1414

1515
- Automatically builds Kustomize configurations from both PR branches
16-
- Generates a diff between base and head configurations
16+
- Generates a diff showing what would actually change upon merge (not just differences between branches)
17+
- Intelligently handles parallel changes to base and feature branches
1718
- Configurable root directory and search depth for Kustomize files
1819
- Commits must meet [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)
1920
- Automated with GitHub Actions ([commit-lint](https://github.com/conventional-changelog/commitlint/#what-is-commitlint))
@@ -22,6 +23,16 @@ Managing Kubernetes configurations across multiple environments and PRs can be c
2223
- Commits must be signed with [Developer Certificate of Origin (DCO)](https://developercertificate.org/)
2324
- Automated with GitHub App ([DCO](https://github.com/apps/dco))
2425

26+
## How It Works
27+
Unlike simple diff tools, this action:
28+
29+
1. Builds Kustomize output from the base branch
30+
1. Creates a temporary merge of the head branch into base (simulating the actual PR merge)
31+
1. Builds Kustomize output from the merged state
32+
1. Compares these outputs to show exactly what would change after merging
33+
34+
This approach correctly handles cases where changes have been made to the base branch in parallel to the feature branch, avoiding misleading diffs that incorrectly suggest changes would be reverted.
35+
2536
## Inputs
2637

2738
| Name | Description | Required | Default |

kustdiff

+43-17
Original file line numberDiff line numberDiff line change
@@ -39,23 +39,22 @@ function safe_filename() {
3939
echo "$1" | sed 's/[^a-zA-Z0-9.]/_/g'
4040
}
4141

42-
function build {
42+
function build_ref {
4343
local ref="$1"
44-
local safe_ref=$(safe_filename "$ref")
44+
local output_dir="$2"
4545
echo "Checking out ref: $ref"
4646
git checkout "$ref" --quiet
47-
mkdir -p "$TMP_DIR/$safe_ref"
47+
mkdir -p "$output_dir"
4848
for envpath in $(get_targets); do
4949
local relative_path="${envpath#$ROOT_DIR/}"
5050
local safe_path=$(safe_filename "$relative_path")
51-
local output_file="$TMP_DIR/$safe_ref/${safe_path}.yaml"
51+
local output_file="$output_dir/${safe_path}.yaml"
5252
echo "Running kustomize for $envpath"
5353
kustomize build "$envpath" -o "$output_file"
5454

55-
# debug_log "Contents of $output_file:"
56-
# debug_log "$(cat "$output_file")"
57-
# debug_log "End of $output_file"
58-
# debug_log "------------------------------------"
55+
if [ "$DEBUG" = "true" ]; then
56+
debug_log "Built kustomize for $envpath to $output_file"
57+
fi
5958
done
6059
}
6160

@@ -65,29 +64,56 @@ function main {
6564
validate_max_depth
6665

6766
git config --global --add safe.directory "$GITHUB_WORKSPACE"
68-
local diff escaped_output output
69-
build "$INPUT_HEAD_REF"
70-
build "$INPUT_BASE_REF"
7167

72-
local safe_head_ref=$(safe_dirname "$INPUT_HEAD_REF")
73-
local safe_base_ref=$(safe_dirname "$INPUT_BASE_REF")
68+
# Save current state to restore later
69+
local current_branch
70+
current_branch=$(git rev-parse --abbrev-ref HEAD)
7471

72+
# Build BASE output
73+
local safe_base_ref=$(safe_filename "$INPUT_BASE_REF")
74+
local base_output_dir="$TMP_DIR/base"
75+
build_ref "$INPUT_BASE_REF" "$base_output_dir"
76+
77+
# Create a temporary merge branch
78+
local merge_branch="temp-merge-$RANDOM"
79+
git checkout -b "$merge_branch" "$INPUT_BASE_REF" --quiet
80+
81+
debug_log "Creating temporary merge of $INPUT_HEAD_REF into $INPUT_BASE_REF"
82+
83+
# Attempt to merge HEAD into BASE
84+
if ! git merge "$INPUT_HEAD_REF" --quiet; then
85+
echo "Merge conflict detected. Cannot automatically merge $INPUT_HEAD_REF into $INPUT_BASE_REF."
86+
git merge --abort
87+
git checkout "$current_branch" --quiet
88+
exit 1
89+
fi
90+
91+
# Build merged output
92+
local merged_output_dir="$TMP_DIR/merged"
93+
build_ref "$merge_branch" "$merged_output_dir"
94+
95+
# Compare outputs
7596
set +e
76-
diff=$(git diff --no-index "$TMP_DIR/$safe_base_ref" "$TMP_DIR/$safe_head_ref")
97+
diff=$(git diff --no-index "$base_output_dir" "$merged_output_dir")
98+
local diff_exit_code=$?
7799

78100
debug_log "Git diff output:"
79101
debug_log "$diff"
80102
debug_log "End of git diff output"
81103
debug_log "------------------------------------"
82104

83-
if [[ -z "$diff" ]]; then
84-
output="No differences found between $INPUT_BASE_REF and $INPUT_HEAD_REF"
105+
# Clean up temporary branches
106+
git checkout "$current_branch" --quiet
107+
git branch -D "$merge_branch" --quiet
108+
109+
if [[ $diff_exit_code -eq 0 ]]; then
110+
output="No differences found in kustomize output after merging $INPUT_HEAD_REF into $INPUT_BASE_REF"
85111
else
86112
# Just pass through the raw git diff output
87113
output="$diff"
88114
fi
89115

90-
escaped_output=${output//$'\n'/'%0A'}
116+
local escaped_output=${output//$'\n'/'%0A'}
91117

92118
if [ ${#escaped_output} -gt 65000 ]; then
93119
escaped_output="Output is greater than 65000 characters, and therefore too large to print as a github comment."

0 commit comments

Comments
 (0)