1
0
Fork 0
mirror of https://github.com/imjasonh/git-k8s synced 2026-07-11 07:59:39 +00:00

Improve e2e smoke test with real git server and push controller exercise

Replace the stub smoke test (which only verified CRD creation) with a
full end-to-end test that:

- Deploys Gitea as an in-cluster git server (emptyDir, auto-install)
- Initializes a test repository with an admin user and initial commit
- Creates GitRepository, GitBranch, and GitPushTransaction CRDs
- Verifies the push controller clones, pushes main to a new branch,
  and transitions the transaction to Succeeded
- Verifies the controller updates the GitBranch CR's headCommit
- Verifies the new branch actually exists on the git server

Also fixes a bug in the push controller's resolveAuth: Secret data
values are base64-encoded when accessed via the dynamic client, but
were being used directly without decoding, causing authentication
failures.

https://claude.ai/code/session_01QfFzqKQUsxxBsiZUhuJ3pG
This commit is contained in:
Claude 2026-02-28 01:06:24 +00:00
parent fe3fe95983
commit aebe5c6c67
No known key found for this signature in database
2 changed files with 204 additions and 6 deletions

View file

@ -92,23 +92,208 @@ jobs:
kubectl get crd gitpushtransactions.git-k8s.imjasonh.com
kubectl get crd gitreposyncs.git-k8s.imjasonh.com
- name: Smoke test - create a GitRepository
- name: Deploy Gitea git server
run: |
cat <<EOF | kubectl apply -f -
cat <<'EOF' | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitea
namespace: git-system
spec:
replicas: 1
selector:
matchLabels:
app: gitea
template:
metadata:
labels:
app: gitea
spec:
containers:
- name: gitea
image: gitea/gitea:1.21
ports:
- containerPort: 3000
name: http
env:
- name: GITEA__database__DB_TYPE
value: sqlite3
- name: GITEA__security__INSTALL_LOCK
value: "true"
readinessProbe:
httpGet:
path: /api/v1/version
port: 3000
initialDelaySeconds: 10
periodSeconds: 5
resources:
requests:
cpu: 100m
memory: 256Mi
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: gitea
namespace: git-system
spec:
selector:
app: gitea
ports:
- port: 3000
targetPort: 3000
name: http
EOF
- name: Wait for Gitea
run: kubectl rollout status deployment/gitea -n git-system --timeout=120s
- name: Initialize Gitea
run: |
# Create admin user.
kubectl exec -n git-system deploy/gitea -- \
gitea admin user create \
--admin \
--username testadmin \
--password testpassword123 \
--email admin@test.local \
--must-change-password=false
# Create test repository with an initial commit on main.
kubectl exec -n git-system deploy/gitea -- \
curl -sf -X POST http://localhost:3000/api/v1/user/repos \
-H 'Content-Type: application/json' \
-u testadmin:testpassword123 \
-d '{"name":"test-repo","auto_init":true,"default_branch":"main"}'
echo ""
echo "Test repository created"
- name: Create Git credentials Secret
run: |
kubectl create secret generic gitea-creds \
--namespace=default \
--from-literal=username=testadmin \
--from-literal=password=testpassword123
- name: Create GitRepository
run: |
cat <<'EOF' | kubectl apply -f -
apiVersion: git-k8s.imjasonh.com/v1alpha1
kind: GitRepository
metadata:
name: test-repo
namespace: default
spec:
url: https://github.com/example/test.git
url: http://gitea.git-system.svc.cluster.local:3000/testadmin/test-repo.git
defaultBranch: main
auth:
secretRef:
name: gitea-creds
EOF
kubectl get gitrepositories -A
- name: Create GitBranch
run: |
cat <<'EOF' | kubectl apply -f -
apiVersion: git-k8s.imjasonh.com/v1alpha1
kind: GitBranch
metadata:
name: test-repo-feature
namespace: default
spec:
repositoryRef: test-repo
branchName: feature-test
EOF
kubectl get gitbranches -A
- name: Push main to a new branch via GitPushTransaction
run: |
cat <<'EOF' | kubectl apply -f -
apiVersion: git-k8s.imjasonh.com/v1alpha1
kind: GitPushTransaction
metadata:
name: test-push
namespace: default
spec:
repositoryRef: test-repo
refSpecs:
- source: refs/heads/main
destination: refs/heads/feature-test
EOF
kubectl get gitpushtransactions -A
- name: Wait for push transaction to succeed
run: |
echo "Waiting for GitPushTransaction to complete..."
for i in $(seq 1 60); do
PHASE=$(kubectl get gitpushtransaction test-push -n default \
-o jsonpath='{.status.phase}' 2>/dev/null)
echo " attempt ${i}: phase=${PHASE:-Pending}"
if [ "$PHASE" = "Succeeded" ]; then
echo "Push transaction succeeded!"
break
elif [ "$PHASE" = "Failed" ]; then
echo "Push transaction FAILED!"
kubectl get gitpushtransaction test-push -n default -o yaml
kubectl logs -n git-system deploy/push-controller --tail=100
exit 1
fi
sleep 2
done
PHASE=$(kubectl get gitpushtransaction test-push -n default \
-o jsonpath='{.status.phase}')
if [ "$PHASE" != "Succeeded" ]; then
echo "Timed out waiting for push transaction (phase: ${PHASE:-empty})"
kubectl logs -n git-system deploy/push-controller --tail=100
exit 1
fi
- name: Verify push transaction result
run: |
echo "=== GitPushTransaction status ==="
kubectl get gitpushtransaction test-push -n default -o yaml
COMMIT=$(kubectl get gitpushtransaction test-push -n default \
-o jsonpath='{.status.resultCommit}')
echo "Result commit: $COMMIT"
if [ -z "$COMMIT" ]; then
echo "FAIL: resultCommit is empty"
exit 1
fi
- name: Verify GitBranch was updated by controller
run: |
echo "=== GitBranch status ==="
kubectl get gitbranch test-repo-feature -n default -o yaml
COMMIT=$(kubectl get gitbranch test-repo-feature -n default \
-o jsonpath='{.status.headCommit}')
echo "GitBranch headCommit: $COMMIT"
if [ -z "$COMMIT" ]; then
echo "FAIL: GitBranch headCommit was not updated by the controller"
exit 1
fi
- name: Verify branch exists on git server
run: |
echo "Listing branches on Gitea..."
kubectl exec -n git-system deploy/gitea -- \
curl -sf http://localhost:3000/api/v1/repos/testadmin/test-repo/branches/feature-test \
-u testadmin:testpassword123
echo ""
echo "Branch feature-test verified on git server!"
- name: Collect diagnostics
if: ${{ failure() }}
uses: chainguard-dev/actions/kind-diag@main
with:
artifact-name: kind-logs
cluster-resources: nodes,namespaces,crds
namespace-resources: pods,deployments,services
namespace-resources: pods,deployments,services,gitrepositories,gitbranches,gitpushtransactions

View file

@ -2,6 +2,7 @@ package push
import (
"context"
"encoding/base64"
"fmt"
"github.com/go-git/go-git/v5"
@ -160,9 +161,21 @@ func (r *Reconciler) resolveAuth(ctx context.Context, namespace string, repo *gi
return nil, fmt.Errorf("reading secret data: found=%v err=%v", found, err)
}
// Secret data values are base64-encoded in the API response when
// accessed via the dynamic client (unlike the typed client which
// decodes automatically into []byte fields).
username, err := base64.StdEncoding.DecodeString(data["username"])
if err != nil {
return nil, fmt.Errorf("decoding username: %w", err)
}
password, err := base64.StdEncoding.DecodeString(data["password"])
if err != nil {
return nil, fmt.Errorf("decoding password: %w", err)
}
return &http.BasicAuth{
Username: data["username"],
Password: data["password"],
Username: string(username),
Password: string(password),
}, nil
}