Skip to content

Commit 1253f33

Browse files
committed
Modernize deployment with Helm, Trivy scanning, and version management
- Add Trivy vulnerability scanner to deploy-to-dev workflow - Scans container images for CRITICAL/HIGH vulnerabilities - Fails build if security issues found - Update deploy-to-test workflow with version management - Requires semantic version input (v1.2.3) - Creates Git tag and GitHub release for new versions (using gh CLI) - Supports rollback to existing versions - Update deploy-to-prod workflow with version validation - Requires version input matching existing Git tag - Verifies image tag exists before deployment - Create Helm chart for eagle-admin - Deployment with 2 replicas, updated resource limits - Service and Route configuration - Environment-specific values files (dev/test/prod) - Update Dockerfile - Upgrade to Node 24 for builder stage - Add apk upgrade for Alpine security patches - Upgrade workflows to Node 24.x (from 22.x) - Delete legacy OpenShift JSON templates
1 parent b45b3b2 commit 1253f33

File tree

15 files changed

+597
-483
lines changed

15 files changed

+597
-483
lines changed

.github/workflows/deploy-to-dev.yaml

Lines changed: 93 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: CI - Build and Deploy to Dev
1+
name: Deploy to Dev
22

33
on:
44
push:
@@ -12,8 +12,10 @@ on:
1212
permissions: write-all
1313

1414
env:
15-
OPENSHIFT_NAMESPACE: 6cdc9e-tools
15+
OPENSHIFT_NAMESPACE_TOOLS: 6cdc9e-tools
16+
OPENSHIFT_NAMESPACE_DEV: 6cdc9e-dev
1617
IMAGE_NAME: eagle-admin
18+
APP_NAME: eagle-admin
1719
TEST_PROMO_BRANCH: promotion/test
1820
TEST_PROMO_PR_BRANCH: promotion/test-pr
1921

@@ -23,7 +25,7 @@ jobs:
2325
runs-on: ubuntu-latest
2426
strategy:
2527
matrix:
26-
node-version: [22.x]
28+
node-version: [24.x]
2729
steps:
2830
- name: Checkout
2931
uses: actions/checkout@v4
@@ -44,7 +46,7 @@ jobs:
4446
needs: install
4547
strategy:
4648
matrix:
47-
node-version: [22.x]
49+
node-version: [24.x]
4850
steps:
4951
- name: Checkout
5052
uses: actions/checkout@v4
@@ -66,7 +68,7 @@ jobs:
6668
needs: install
6769
strategy:
6870
matrix:
69-
node-version: [22.x]
71+
node-version: [24.x]
7072
steps:
7173
- name: Checkout
7274
uses: actions/checkout@v4
@@ -82,13 +84,13 @@ jobs:
8284
- run: yarn install --immutable
8385
- run: yarn test-ci
8486

85-
build-check:
86-
name: Build Verification
87+
build:
88+
name: Build
8789
runs-on: ubuntu-latest
8890
needs: install
8991
strategy:
9092
matrix:
91-
node-version: [22.x]
93+
node-version: [24.x]
9294
steps:
9395
- name: Checkout
9496
uses: actions/checkout@v4
@@ -104,10 +106,10 @@ jobs:
104106
- run: yarn install --immutable
105107
- run: yarn build
106108

107-
build:
108-
name: Build and Push Image
109+
scan:
110+
name: Security Scan
109111
runs-on: ubuntu-latest
110-
needs: [lint, test, build-check]
112+
needs: [lint, test, build]
111113
outputs:
112114
SHORT_SHA: ${{ steps.short-sha.outputs.SHA }}
113115
steps:
@@ -118,6 +120,34 @@ jobs:
118120
id: short-sha
119121
run: echo "SHA=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
120122

123+
- name: Build Docker image for scanning
124+
uses: docker/build-push-action@v6
125+
with:
126+
context: .
127+
push: false
128+
tags: ${{ env.IMAGE_NAME }}:${{ steps.short-sha.outputs.SHA }}
129+
load: true
130+
131+
- name: Run Trivy vulnerability scanner
132+
uses: aquasecurity/trivy-action@master
133+
with:
134+
image-ref: ${{ env.IMAGE_NAME }}:${{ steps.short-sha.outputs.SHA }}
135+
format: 'table'
136+
exit-code: '1'
137+
ignore-unfixed: true
138+
vuln-type: 'os,library'
139+
severity: 'CRITICAL,HIGH'
140+
141+
push:
142+
name: Push Image
143+
runs-on: ubuntu-latest
144+
needs: scan
145+
outputs:
146+
SHORT_SHA: ${{ needs.scan.outputs.SHORT_SHA }}
147+
steps:
148+
- name: Checkout repository
149+
uses: actions/checkout@v4
150+
121151
- name: Login to OpenShift registry
122152
uses: docker/login-action@v3
123153
with:
@@ -131,22 +161,65 @@ jobs:
131161
context: .
132162
push: true
133163
tags: |
134-
${{ secrets.OPENSHIFT_REPOSITORY }}/${{ env.OPENSHIFT_NAMESPACE }}/${{ env.IMAGE_NAME }}:dev
135-
${{ secrets.OPENSHIFT_REPOSITORY }}/${{ env.OPENSHIFT_NAMESPACE }}/${{ env.IMAGE_NAME }}:ci-latest
136-
${{ secrets.OPENSHIFT_REPOSITORY }}/${{ env.OPENSHIFT_NAMESPACE }}/${{ env.IMAGE_NAME }}:${{ steps.short-sha.outputs.SHA }}
164+
${{ secrets.OPENSHIFT_REPOSITORY }}/${{ env.OPENSHIFT_NAMESPACE_TOOLS }}/${{ env.IMAGE_NAME }}:dev
165+
${{ secrets.OPENSHIFT_REPOSITORY }}/${{ env.OPENSHIFT_NAMESPACE_TOOLS }}/${{ env.IMAGE_NAME }}:ci-latest
166+
${{ secrets.OPENSHIFT_REPOSITORY }}/${{ env.OPENSHIFT_NAMESPACE_TOOLS }}/${{ env.IMAGE_NAME }}:${{ needs.scan.outputs.SHORT_SHA }}
137167
labels: |
138168
commit.author=${{ github.event.head_commit.author.email }}
139169
commit.id=${{ github.event.head_commit.id }}
140170
commit.timestamp=${{ github.event.head_commit.timestamp }}
141171
commit.message=${{ github.event.head_commit.message }}
142172
173+
deploy:
174+
name: Deploy to Dev
175+
needs: push
176+
runs-on: ubuntu-latest
177+
steps:
178+
- name: Checkout repository
179+
uses: actions/checkout@v4
180+
181+
- name: Install OpenShift CLI
182+
run: |
183+
curl -LO "https://mirror.openshift.com/pub/openshift-v4/clients/ocp/latest/openshift-client-linux.tar.gz"
184+
tar -xvzf openshift-client-linux.tar.gz
185+
sudo mv oc /usr/local/bin/
186+
rm -f openshift-client-linux.tar.gz
187+
188+
- name: Install Helm
189+
run: |
190+
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
191+
helm version
192+
193+
- name: Log into OpenShift
194+
uses: redhat-actions/oc-login@v1
195+
with:
196+
openshift_server_url: ${{ secrets.OPENSHIFT_URL }}
197+
openshift_token: ${{ secrets.OPENSHIFT_TOKEN }}
198+
namespace: ${{ env.OPENSHIFT_NAMESPACE_DEV }}
199+
200+
- name: Deploy with Helm
201+
run: |
202+
helm upgrade --install ${{ env.APP_NAME }} ./helm/${{ env.APP_NAME }} \
203+
--namespace ${{ env.OPENSHIFT_NAMESPACE_DEV }} \
204+
--values ./helm/${{ env.APP_NAME }}/values-dev.yaml \
205+
--set image.tag=dev \
206+
--wait --timeout=5m
207+
208+
echo "Restarting deployment to pull updated image..."
209+
oc rollout restart deployment/${{ env.APP_NAME }} -n ${{ env.OPENSHIFT_NAMESPACE_DEV }}
210+
211+
- name: Verify deployment
212+
run: |
213+
echo "Waiting for rollout to complete..."
214+
oc rollout status deployment/${{ env.APP_NAME }} -n ${{ env.OPENSHIFT_NAMESPACE_DEV }} --timeout=5m
215+
216+
echo "Deployment successful!"
217+
oc get pods -n ${{ env.OPENSHIFT_NAMESPACE_DEV }} -l app.kubernetes.io/name=${{ env.APP_NAME }}
218+
143219
promotion:
144220
name: Create Promotion Pull Request
145-
needs: build
221+
needs: push
146222
runs-on: ubuntu-latest
147-
strategy:
148-
matrix:
149-
node-version: [24.x]
150223
steps:
151224
# Update promotion/test-pr with new commit hash
152225
- name: Checkout promotion/test
@@ -162,14 +235,14 @@ jobs:
162235
git checkout -B ${{ env.TEST_PROMO_PR_BRANCH }}
163236
git reset --hard ${{ env.TEST_PROMO_BRANCH }}
164237
165-
echo $(jq '.commit="${{ needs.build.outputs.SHORT_SHA }}"' state.json) > state.json
238+
echo $(jq '.commit="${{ needs.push.outputs.SHORT_SHA }}"' state.json) > state.json
166239
167240
# Only commit if there are changes
168241
if git diff --quiet state.json; then
169242
echo "No changes to state.json, skipping commit"
170243
echo "has_changes=false" >> $GITHUB_OUTPUT
171244
else
172-
git commit -am "Promote commit ${{ needs.build.outputs.SHORT_SHA }} to Test"
245+
git commit -am "Promote commit ${{ needs.push.outputs.SHORT_SHA }} to Test"
173246
git push --force origin ${{ env.TEST_PROMO_PR_BRANCH }}
174247
echo "has_changes=true" >> $GITHUB_OUTPUT
175248
fi

.github/workflows/deploy-to-prod.yaml

Lines changed: 63 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,82 @@ name: Deploy to Prod
22

33
on:
44
workflow_dispatch:
5+
inputs:
6+
version:
7+
description: 'Version tag to promote (e.g., v1.2.3)'
8+
required: true
9+
type: string
510

611
permissions: write-all
712

813
env:
9-
OPENSHIFT_NAMESPACE: 6cdc9e-tools
14+
OPENSHIFT_NAMESPACE_TOOLS: 6cdc9e-tools
15+
OPENSHIFT_NAMESPACE_PROD: 6cdc9e-prod
1016
IMAGE_NAME: eagle-admin
17+
APP_NAME: eagle-admin
1118

1219
jobs:
13-
build:
14-
name: Build and Push Image
20+
validate:
21+
name: Validate Version
1522
runs-on: ubuntu-latest
1623
steps:
1724
- name: Checkout repository
1825
uses: actions/checkout@v4
26+
with:
27+
fetch-depth: 0
28+
29+
- name: Validate version format
30+
run: |
31+
if [[ ! "${{ inputs.version }}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
32+
echo "Error: Version must be in format v1.2.3"
33+
exit 1
34+
fi
1935
20-
- name: Get Short SHA
21-
id: short-sha
22-
run: echo "SHA=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
36+
- name: Verify Git tag exists
37+
run: |
38+
if ! git rev-parse "${{ inputs.version }}" >/dev/null 2>&1; then
39+
echo "Error: Git tag ${{ inputs.version }} does not exist"
40+
echo "Please deploy to test first to create the version"
41+
exit 1
42+
fi
43+
echo "Git tag ${{ inputs.version }} verified"
2344
24-
- name: Login to OpenShift registry
25-
uses: docker/login-action@v3
45+
deploy:
46+
name: Deploy to Prod
47+
needs: validate
48+
runs-on: ubuntu-latest
49+
steps:
50+
- name: Install OpenShift CLI
51+
uses: redhat-actions/openshift-tools-installer@v1
2652
with:
27-
registry: ${{ secrets.OPENSHIFT_REPOSITORY }}
28-
username: ${{ secrets.OPENSHIFT_REPOSITORY_USERNAME }}
29-
password: ${{ secrets.OPENSHIFT_REPOSITORY_PASSWORD }}
53+
oc: "4.14"
3054

31-
- name: Build and push Docker image
32-
uses: docker/build-push-action@v6
55+
- name: Log into OpenShift
56+
uses: redhat-actions/oc-login@v1
3357
with:
34-
context: .
35-
push: true
36-
tags: |
37-
${{ secrets.OPENSHIFT_REPOSITORY }}/${{ env.OPENSHIFT_NAMESPACE }}/${{ env.IMAGE_NAME }}:prod
38-
${{ secrets.OPENSHIFT_REPOSITORY }}/${{ env.OPENSHIFT_NAMESPACE }}/${{ env.IMAGE_NAME }}:${{ steps.short-sha.outputs.SHA }}
39-
labels: |
40-
commit.id=${{ github.sha }}
41-
commit.timestamp=${{ github.event.head_commit.timestamp }}
58+
openshift_server_url: ${{ secrets.OPENSHIFT_URL }}
59+
openshift_token: ${{ secrets.OPENSHIFT_TOKEN }}
60+
namespace: ${{ env.OPENSHIFT_NAMESPACE_TOOLS }}
61+
62+
- name: Verify image tag exists
63+
run: |
64+
echo "Verifying image tag ${{ inputs.version }} exists..."
65+
if ! oc -n ${{ env.OPENSHIFT_NAMESPACE_TOOLS }} get imagestreamtag ${{ env.IMAGE_NAME }}:${{ inputs.version }} &>/dev/null; then
66+
echo "Error: Image tag ${{ inputs.version }} does not exist"
67+
exit 1
68+
fi
69+
echo "Image tag verified"
70+
71+
- name: Tag version as prod
72+
run: |
73+
echo "Tagging ${{ inputs.version }} as prod..."
74+
oc -n ${{ env.OPENSHIFT_NAMESPACE_TOOLS }} tag \
75+
${{ env.IMAGE_NAME }}:${{ inputs.version }} ${{ env.IMAGE_NAME }}:prod
76+
77+
- name: Deploy to prod
78+
run: |
79+
oc -n ${{ env.OPENSHIFT_NAMESPACE_PROD }} rollout restart deployment/${{ env.APP_NAME }}
80+
oc -n ${{ env.OPENSHIFT_NAMESPACE_PROD }} rollout status deployment/${{ env.APP_NAME }} --timeout=5m
81+
82+
echo "Deployment successful!"
83+
oc get pods -n ${{ env.OPENSHIFT_NAMESPACE_PROD }} -l app.kubernetes.io/name=${{ env.APP_NAME }}

0 commit comments

Comments
 (0)