Skip to content
This repository was archived by the owner on Nov 23, 2025. It is now read-only.

Commit 572a093

Browse files
authored
Merge pull request #16 from TechTorque-2025/dev
Dev
2 parents 62119b6 + fc7e7a5 commit 572a093

6 files changed

Lines changed: 164 additions & 72 deletions

File tree

.github/workflows/build-test.yaml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Build and Test
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- 'main'
7+
- 'dev'
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
build-test:
14+
name: Build and Test
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v4
20+
21+
- name: Set up Go
22+
uses: actions/setup-go@v4
23+
with:
24+
go-version: '1.21'
25+
cache: true
26+
27+
- name: Build
28+
run: go build -v ./...
29+
30+
- name: Test Summary
31+
run: |
32+
echo "### ✅ Build Successful" >> $GITHUB_STEP_SUMMARY
33+
echo "Go build completed successfully" >> $GITHUB_STEP_SUMMARY
34+
echo "Ready for review and merge" >> $GITHUB_STEP_SUMMARY

.github/workflows/build.yaml

Lines changed: 25 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,41 @@
1-
# API_Gateway/.github/workflows/build.yml
2-
# This workflow builds, tests, AND packages the Go API Gateway
3-
4-
name: Build, Test, and Package Gateway
1+
name: Build and Push Docker Image
52

63
on:
74
push:
85
branches:
96
- 'main'
10-
- 'devOps'
11-
- 'dev'
12-
pull_request:
13-
branches:
14-
- 'main'
15-
- 'devOps'
167
- 'dev'
178

189
permissions:
1910
contents: read
20-
packages: write
11+
packages: write
2112

2213
jobs:
23-
# --- JOB 1: Build and Test (From your file) ---
24-
# This runs on all pushes AND all pull requests to verify the code
25-
build-and-test:
26-
name: Build and Smoke Test
14+
build-and-push:
15+
name: Build & Push Docker Image
2716
runs-on: ubuntu-latest
2817

2918
steps:
3019
- name: Checkout code
3120
uses: actions/checkout@v4
3221

33-
- name: Set up Go
34-
uses: actions/setup-go@v5
35-
with:
36-
go-version: '1.22'
37-
cache-dependency-path: go.mod
38-
39-
- name: Download dependencies
40-
run: go mod download
41-
42-
- name: Build Go Application
43-
run: go build -v -o ./app ./cmd/gateway
44-
45-
- name: Verify config.yaml exists
22+
- name: Extract branch name
23+
id: branch
4624
run: |
47-
if [ ! -f config.yaml ]; then
48-
echo "Error: config.yaml not found!"
49-
exit 1
50-
fi
51-
echo "✓ config.yaml found"
25+
BRANCH_NAME=${GITHUB_REF#refs/heads/}
26+
echo "name=${BRANCH_NAME}" >> $GITHUB_OUTPUT
27+
echo "📍 Building for branch: ${BRANCH_NAME}"
5228
53-
- name: Start Gateway (smoke test)
54-
run: |
55-
echo "Starting API Gateway with config.yaml..."
56-
# We need to set a dummy secret for the smoke test
57-
export JWT_SECRET="dummy-secret-for-test"
58-
timeout 5s ./app || code=$?
59-
if [ ${code:-0} -eq 124 ]; then
60-
echo "✓ Gateway started successfully (terminated after 5s)"
61-
exit 0
62-
elif [ ${code:-0} -eq 0 ]; then
63-
echo "✓ Gateway started and stopped cleanly"
64-
exit 0
65-
else
66-
echo "✗ Gateway failed to start (exit code: ${code})"
67-
exit 1
68-
fi
69-
70-
# --- JOB 2: Package as Docker Image (From my file) ---
71-
# This runs ONLY after Job 1 succeeds, AND
72-
# This runs ONLY on pushes to your main branches (not PRs)
73-
build-and-push-docker:
74-
name: Build & Push Docker Image
75-
needs: build-and-test # Depends on the first job
76-
77-
# This logic ensures it only runs on pushes, not PRs
78-
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/devOps' || github.ref == 'refs/heads/dev')
79-
runs-on: ubuntu-latest
80-
81-
steps:
82-
- name: Checkout code
83-
uses: actions/checkout@v4
84-
85-
- name: Docker meta
29+
- name: Docker meta (with branch-aware tags)
8630
id: meta
8731
uses: docker/metadata-action@v5
8832
with:
89-
images: ghcr.io/${{ github.repository }}
33+
images: ghcr.io/techtorque-2025/api_gateway
9034
tags: |
91-
type=sha,prefix=
92-
type:raw,value=latest,enable={{is_default_branch}}
35+
type=raw,value=${{ steps.branch.outputs.name }}-{{sha}},enable=true
36+
type=raw,value=latest,enable={{is_default_branch}}
37+
flavor: |
38+
latest=false
9339
9440
- name: Log in to GHCR
9541
uses: docker/login-action@v3
@@ -102,7 +48,15 @@ jobs:
10248
uses: docker/build-push-action@v5
10349
with:
10450
context: .
105-
file: ./Dockerfile
10651
push: true
10752
tags: ${{ steps.meta.outputs.tags }}
108-
labels: ${{ steps.meta.outputs.labels }}
53+
labels: ${{ steps.meta.outputs.labels }}
54+
55+
- name: Image Summary
56+
run: |
57+
echo "### 🐳 Docker Image Built" >> $GITHUB_STEP_SUMMARY
58+
echo "" >> $GITHUB_STEP_SUMMARY
59+
echo "**Tags pushed:**" >> $GITHUB_STEP_SUMMARY
60+
echo '```' >> $GITHUB_STEP_SUMMARY
61+
echo "${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY
62+
echo '```' >> $GITHUB_STEP_SUMMARY
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# GitHub Actions Workflow Template for GitOps with ArgoCD
2+
# This workflow should replace the old deploy.yaml in each microservice repo
3+
4+
name: Update K8s Manifest
5+
6+
on:
7+
workflow_run:
8+
workflows: ["Build and Push Docker Image"]
9+
types: [completed]
10+
branches: ['main', 'dev']
11+
12+
jobs:
13+
update-manifest:
14+
name: Update Image Tag in k8s-config
15+
if: ${{ github.event.workflow_run.conclusion == 'success' }}
16+
runs-on: ubuntu-latest
17+
18+
steps:
19+
- name: Get branch and SHA info
20+
id: info
21+
run: |
22+
BRANCH="${{ github.event.workflow_run.head_branch }}"
23+
SHORT_SHA="$(echo ${{ github.event.workflow_run.head_sha }} | cut -c1-7)"
24+
echo "branch=${BRANCH}" >> $GITHUB_OUTPUT
25+
echo "sha=${SHORT_SHA}" >> $GITHUB_OUTPUT
26+
echo "📍 Branch: ${BRANCH}, SHA: ${SHORT_SHA}"
27+
28+
- name: Checkout k8s-config repo (matching branch)
29+
uses: actions/checkout@v4
30+
with:
31+
repository: 'TechTorque-2025/k8s-config'
32+
token: ${{ secrets.REPO_ACCESS_TOKEN }}
33+
ref: ${{ steps.info.outputs.branch }} # Checkout dev or main to match microservice branch
34+
path: 'k8s-config'
35+
36+
- name: Install yq (YAML processor)
37+
run: |
38+
sudo wget -qO /usr/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
39+
sudo chmod +x /usr/bin/yq
40+
41+
- name: Update image tag in deployment manifest
42+
env:
43+
SERVICE_NAME: "api_gateway" # e.g., "timelogging_service", "frontend_web", "authentication"
44+
DEPLOYMENT_FILE: "gateway-deployment.yaml" # e.g., "timelogging-deployment.yaml", "frontend-deployment.yaml"
45+
run: |
46+
cd k8s-config
47+
NEW_IMAGE="ghcr.io/techtorque-2025/${SERVICE_NAME}:${{ steps.info.outputs.branch }}-${{ steps.info.outputs.sha }}"
48+
export NEW_IMAGE
49+
50+
echo "🔄 Updating ${DEPLOYMENT_FILE} to use image: ${NEW_IMAGE}"
51+
52+
yq eval -i \
53+
'(select(.kind == "Deployment") | .spec.template.spec.containers[0].image) = env(NEW_IMAGE)' \
54+
k8s/services/${DEPLOYMENT_FILE}
55+
56+
echo "✅ Updated manifest:"
57+
yq eval 'select(.kind == "Deployment") | .spec.template.spec.containers[0].image' k8s/services/${DEPLOYMENT_FILE}
58+
59+
- name: Commit and push changes
60+
env:
61+
SERVICE_NAME: "api_gateway"
62+
run: |
63+
cd k8s-config
64+
git config user.name "github-actions[bot]"
65+
git config user.email "github-actions[bot]@users.noreply.github.com"
66+
67+
git add k8s/services/
68+
69+
if git diff --cached --quiet; then
70+
echo "⚠️ No changes detected, skipping commit"
71+
exit 0
72+
fi
73+
74+
git commit -m "chore(${SERVICE_NAME}): update image to ${{ steps.info.outputs.branch }}-${{ steps.info.outputs.sha }}" \
75+
-m "Triggered by: ${{ github.event.workflow_run.html_url }}"
76+
77+
git push origin ${{ steps.info.outputs.branch }}
78+
79+
echo "✅ Pushed manifest update to k8s-config/${{ steps.info.outputs.branch }}"
80+
echo "🚀 ArgoCD will automatically deploy this change"
81+
82+
- name: Summary
83+
run: |
84+
echo "### 🎉 Manifest Update Complete" >> $GITHUB_STEP_SUMMARY
85+
echo "" >> $GITHUB_STEP_SUMMARY
86+
echo "- **Branch**: ${{ steps.info.outputs.branch }}" >> $GITHUB_STEP_SUMMARY
87+
echo "- **Image Tag**: ${{ steps.info.outputs.branch }}-${{ steps.info.outputs.sha }}" >> $GITHUB_STEP_SUMMARY
88+
echo "- **Manifest Updated**: k8s/services/gateway-deployment.yaml" >> $GITHUB_STEP_SUMMARY
89+
echo "- **Next Step**: ArgoCD will sync this change to the cluster" >> $GITHUB_STEP_SUMMARY

cmd/gateway/main.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,21 @@ func newProxy(targetURL, stripPrefix string) (*httputil.ReverseProxy, error) {
9898
proxy := httputil.NewSingleHostReverseProxy(target)
9999
originalDirector := proxy.Director
100100
proxy.Director = func(req *http.Request) {
101+
// Store the custom headers before calling originalDirector
102+
userSubject := req.Header.Get("X-User-Subject")
103+
userRoles := req.Header.Get("X-User-Roles")
104+
101105
originalDirector(req)
102106
req.Host = target.Host
107+
108+
// Re-apply custom headers after originalDirector (which may create a new header map)
109+
if userSubject != "" {
110+
req.Header.Set("X-User-Subject", userSubject)
111+
}
112+
if userRoles != "" {
113+
req.Header.Set("X-User-Roles", userRoles)
114+
}
115+
103116
if stripPrefix != "" {
104117
req.URL.Path = strings.TrimPrefix(req.URL.Path, stripPrefix)
105118
}
@@ -182,6 +195,8 @@ func injectUserInfo(next http.Handler) http.Handler {
182195
}
183196
logger.Info("Injecting user info into headers", "subject", r.Header.Get("X-User-Subject"), "roles", r.Header.Get("X-User-Roles"))
184197
}
198+
// NOTE: The Authorization header is already present in r.Header and will be
199+
// automatically forwarded by the reverse proxy to downstream services
185200
next.ServeHTTP(w, r)
186201
})
187202
}

config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,6 @@ services:
116116
- name: "ai"
117117
path_prefix: "/api/v1/ai/"
118118
target_url: "http://localhost:8091" # Agent Bot service (Python FastAPI)
119-
strip_prefix: "" # Don't strip - Agent Bot expects the full path
119+
strip_prefix: "/api/v1/ai" # Strip to match Agent Bot's internal routing
120120
auth_required: true
121121
env_var: "AGENT_BOT_SERVICE_URL"

0 commit comments

Comments
 (0)