Skip to content

Commit ee91cff

Browse files
LIMA-27098: github actions workflow (#29)
* feat: add source code * feat: add skaffold deployment and kustomization * feat: skaffold deployment with kustomize * feat: add github actions for easytrade building * chore: delete not needed readme template * docs: update READMEs * feat: adding tools to improve development * feat: update kubernetes manifests * feat: add skaffold profiles * docs: remove useless comments * ci: set easytrade locations * ci: master build * ci: final adjustments * ci: add paths triggering workflows * ci: change branch path to main in master build workflow * ci: add workflow for snyk scanning * ci: add secrets declaration * ci: adding snyk job in branch&master workflows * ci: add .github dir to the workflow trigger paths * ci: replace security-severity for license-related findings in snyk * ci: fix colon syntax error * ci: fix typo * ci: always trigger step with security-severity replacement * chore: update libs suggested by snyk * ci: fix json-smart version * ci: fix json-smart dependency * chore: update poetry lock file * chore: update poetry lock * fix: adjust paths in skaffold file
1 parent fd83f05 commit ee91cff

File tree

23 files changed

+767
-122
lines changed

23 files changed

+767
-122
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: Check credit card order
2+
description: Fetch and check the status of the credit card
3+
4+
inputs:
5+
user_id:
6+
description: ID of the credit card owner
7+
default: "3"
8+
namespace:
9+
description: Kubernetes namespace in which EasyTrade is deployed
10+
default: "easytrade"
11+
12+
outputs:
13+
result:
14+
description: Validation result
15+
value: ${{ steps.check-credit-card-order.outputs.result }}
16+
17+
runs:
18+
using: composite
19+
steps:
20+
- name: Check credit card order
21+
id: check-credit-card-order
22+
shell: bash
23+
run: |
24+
RESPONSE=$(./.github/actions/scripts/curl-on-cluster.sh ${{ inputs.namespace }} \
25+
-sLX GET 'credit-card-order-service:8080/v1/orders/${{ inputs.user_id }}/status/latest' \
26+
-H 'accept: application/json')
27+
echo "Response: [${RESPONSE}]"
28+
29+
STATUS=$(echo $RESPONSE | jq -re '.results.status')
30+
echo "Latest card status: [${STATUS}]"
31+
32+
if [[ "$STATUS" == "card_delivered" ]]; then
33+
echo Credit card order test passed
34+
echo "result=pass" >>$GITHUB_OUTPUT
35+
exit 0
36+
else
37+
echo "::error::Credit card order test failed"
38+
echo "result=fail" >>$GITHUB_OUTPUT
39+
exit 1
40+
fi
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Get access token
2+
description: Fetch access token for an OAuth client
3+
4+
inputs:
5+
client_id:
6+
description: OAuth Client ID
7+
required: true
8+
client_secret:
9+
description: OAuth Client Secret
10+
required: true
11+
sso_url:
12+
description: URL of SSO used by the tenant
13+
required: true
14+
15+
outputs:
16+
token:
17+
description: Generated token
18+
value: ${{ steps.get-token.outputs.token }}
19+
20+
runs:
21+
using: composite
22+
steps:
23+
- name: Get token
24+
id: get-token
25+
shell: bash
26+
run: |
27+
TOKEN=$(curl -sfLX POST "${{ inputs.sso_url }}" \
28+
--header "Content-Type: application/x-www-form-urlencoded" \
29+
--data-urlencode "grant_type=client_credentials" \
30+
--data-urlencode "client_id=${{ inputs.client_id }}" \
31+
--data-urlencode "client_secret=${{ inputs.client_secret }}" \
32+
--data-urlencode "scope=storage:buckets:read storage:bizevents:read storage:events:write" \
33+
| jq -re '.access_token')
34+
35+
echo "::add-mask::$TOKEN"
36+
echo "token=$TOKEN" >> $GITHUB_OUTPUT
37+
echo "Generated new token"
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: Get validation result
2+
description: Fetch and check the validation workflow result
3+
4+
inputs:
5+
access_token:
6+
description: Authentication token for the Dynatrace tenant
7+
required: true
8+
tenant_url:
9+
description: URL of the Dynatrace tenant
10+
required: true
11+
event_type:
12+
description: Event type of the validation result event
13+
required: true
14+
timeframe:
15+
description: Timeframe for validation
16+
required: true
17+
job_id:
18+
description: Job ID
19+
required: true
20+
retries:
21+
description: Retry count limit
22+
default: "3"
23+
required: true
24+
interval_seconds:
25+
description: Interval between retires in seconds
26+
default: "30"
27+
required: true
28+
29+
outputs:
30+
result:
31+
description: Validation result
32+
value: ${{ steps.get-validation-result.outputs.result }}
33+
34+
runs:
35+
using: composite
36+
steps:
37+
- name: Get result of Validation
38+
id: get-validation-result
39+
shell: bash
40+
env:
41+
ACCESS_TOKEN: ${{ inputs.access_token }}
42+
TENANT_URL: ${{ inputs.tenant_url }}
43+
EVENT_TYPE: ${{ inputs.event_type }}
44+
TIMEFRAME: ${{ inputs.timeframe }}
45+
JOB_ID: ${{ github.run_number }}-${{ github.sha }}
46+
RETRIES: ${{ inputs.retries }}
47+
INTERVAL_SECONDS: ${{ inputs.interval_seconds }}
48+
run: ./.github/actions/scripts/get-validation-result.sh
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Order credit card
2+
description: Order a new credit card in the EasyTrade application
3+
4+
inputs:
5+
user_id:
6+
description: ID of the credit card owner
7+
default: "3"
8+
namespace:
9+
description: Kubernetes namespace in which EasyTrade is deployed
10+
default: "easytrade"
11+
12+
runs:
13+
using: composite
14+
steps:
15+
- name: Get token
16+
shell: bash
17+
run: |
18+
BODY='{
19+
"accountId": ${{ inputs.user_id }},
20+
"email": "[email protected]",
21+
"name": "Demo User",
22+
"shippingAddress": "ulica Andersa 352 91-682 Ilaw",
23+
"cardLevel": "Platinum"
24+
}'
25+
26+
RESPONSE=$(./.github/actions/scripts/curl-on-cluster.sh ${{ inputs.namespace }} \
27+
-sLX POST 'credit-card-order-service:8080/v1/orders' \
28+
-H 'accept: application/json' \
29+
-H 'Content-Type: application/json' \
30+
-d "${BODY}")
31+
echo "Card ordered, response: [${RESPONSE}]"
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: Run validation
2+
description: Start validation workflow and check the result
3+
4+
inputs:
5+
client_id:
6+
description: OAuth Client ID
7+
required: true
8+
client_secret:
9+
description: OAuth Client Secret
10+
required: true
11+
sso_url:
12+
description: URL of SSO used by the tenant
13+
required: true
14+
tenant_url:
15+
description: URL of the Dynatrace tenant
16+
required: true
17+
18+
runs:
19+
using: composite
20+
steps:
21+
- uses: ./.github/actions/get-access-token
22+
id: get-access-token
23+
with:
24+
client_id: ${{ inputs.client_id }}
25+
client_secret: ${{ inputs.client_secret }}
26+
sso_url: ${{ inputs.sso_url }}
27+
28+
- name: Trigger validation
29+
uses: ./.github/actions/send-bizevent
30+
with:
31+
access_token: ${{ steps.get-access-token.outputs.token }}
32+
tenant_url: ${{ inputs.tenant_url }}
33+
bizevent_body: |
34+
{
35+
"timeframe.from": "now-15m",
36+
"timeframe.to": "now",
37+
"srg.variable.timeframe": 15,
38+
"event.provider": "Github Actions",
39+
"event.type": "demoability.validation.trigger",
40+
"tags.application": "easytrade-k8s",
41+
"tags.job.id": "${{ github.run_number }}-${{ github.sha }}"
42+
}
43+
44+
- uses: ./.github/actions/get-validation-result
45+
with:
46+
access_token: ${{ steps.get-access-token.outputs.token }}
47+
tenant_url: ${{ inputs.tenant_url }}
48+
event_type: demoability.validation.result
49+
timeframe: 5m
50+
job_id: ${{ github.run_number }}-${{ github.sha }}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/bin/bash
2+
3+
if [ "$#" -lt 2 ]; then
4+
echo >&2 "Usage: ./curl-on-cluster.sh <NAMESPACE> <CURL ARGS>"
5+
exit 1
6+
fi
7+
8+
NAMESPACE=$1
9+
shift
10+
ARGS=("$@")
11+
POD_NAME=curl-$(date +%s%N)
12+
13+
echo >&2 "Running 'curl ${ARGS[@]}' in the pod $NAMESPACE/$POD_NAME"
14+
15+
kubectl run -n $NAMESPACE $POD_NAME --restart=Never --image=curlimages/curl -- "${ARGS[@]}" >&2
16+
17+
kubectl wait -n $NAMESPACE --for=jsonpath="{.status.containerStatuses[*].state.terminated}" --timeout=30s pod/$POD_NAME >&2
18+
19+
OUTPUT=$(kubectl logs -n $NAMESPACE $POD_NAME)
20+
21+
kubectl delete -n $NAMESPACE pod $POD_NAME >&2
22+
23+
echo $OUTPUT
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/bin/bash
2+
3+
getValidationResult() {
4+
URL=${TENANT_URL}/platform/storage/query/v1/query:execute?enrich=metric-metadata
5+
6+
QUERY="fetch bizevents, from: now() - ${TIMEFRAME} | filter event.type == \"${EVENT_TYPE}\" and tags.job.id == \"${JOB_ID}\""
7+
echo Running DQL query: $QUERY
8+
9+
BODY=$(jq -cn --arg query "$QUERY" --argjson requestTimeoutMilliseconds 1000 '$ARGS.named')
10+
11+
RESPONSE=$(curl -sfLX POST "$URL" \
12+
--header "Content-Type: application/json" \
13+
--header "Accept: application/json" \
14+
--header "Authorization: Bearer ${ACCESS_TOKEN}" \
15+
--data-raw "${BODY}")
16+
RESULT=$(echo $RESPONSE | jq -re '.result.records[0].result')
17+
18+
echo Found result [${RESULT}] for job [JOB_ID::${JOB_ID}]
19+
if [[ "$RESULT" == "pass" ]]; then
20+
return 0
21+
fi
22+
23+
return 1
24+
}
25+
26+
for ATTEMPT in $(seq 1 $RETRIES); do
27+
echo "Waiting [${INTERVAL_SECONDS}s] for results of job [JOB_ID::${JOB_ID}] try [${ATTEMPT}/${RETRIES}]"
28+
sleep $INTERVAL_SECONDS
29+
30+
if getValidationResult; then
31+
echo "Successfully validated the deployment"
32+
echo "result=pass" >>$GITHUB_OUTPUT
33+
exit 0
34+
fi
35+
done
36+
37+
echo "::error::Failed to validate deployment"
38+
echo "result=fail" >>$GITHUB_OUTPUT
39+
exit 1
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/bin/bash
2+
3+
replace_all() {
4+
FROM=$1
5+
TO=$2
6+
echo "Replacing [$FROM] with [$TO]"
7+
grep -rl $FROM . --exclude-dir={.git,node_modules,bin,obj,build} | xargs sed -i "s/$FROM/$TO/g"
8+
}
9+
10+
BUILD_VERSION=$1
11+
WORKDIR=${2:-.}
12+
BUILD_DATE=${3:-$(date '+%Y-%m-%d %H:%M')}
13+
BUILD_COMMIT=${4:-$(git log --pretty=format:'%h' -n 1)}
14+
15+
if [ -z "$BUILD_VERSION" ]; then
16+
echo "Build version not set"
17+
exit 1
18+
fi
19+
20+
cd $WORKDIR
21+
22+
echo "Build version: $BUILD_VERSION, date: $BUILD_DATE, commit: $BUILD_COMMIT, path: $(pwd)"
23+
24+
replace_all "1.0.0-easytrade" "$BUILD_VERSION"
25+
replace_all "{{BUILD_VERSION}}" "$BUILD_VERSION"
26+
replace_all "{{BUILD_DATE}}" "$BUILD_DATE"
27+
replace_all "{{BUILD_COMMIT}}" "$BUILD_COMMIT"
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: Send bizevent
2+
description: Push a bizevent to the Dynatrace tenant
3+
4+
inputs:
5+
access_token:
6+
description: Authentication token for the Dynatrace tenant
7+
required: true
8+
tenant_url:
9+
description: URL of the Dynatrace tenant
10+
required: true
11+
bizevent_body:
12+
description: JSON body of the bizevent
13+
required: true
14+
15+
runs:
16+
using: composite
17+
steps:
18+
- name: Send bizevent
19+
shell: bash
20+
run: |
21+
curl -sfLX POST "${{ inputs.tenant_url }}/platform/classic/environment-api/v2/bizevents/ingest" \
22+
--header "Content-Type: application/json" \
23+
--header "Authorization: Bearer ${{ inputs.access_token }}" \
24+
--data-raw "$(echo '${{ inputs.bizevent_body }}' | jq -c)"
25+
26+
echo "Bizevent sent"
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
name: Set version
2+
description: Set EasyTrade release version
3+
4+
inputs:
5+
version:
6+
description: Version of the EasyTrade application
7+
required: true
8+
9+
runs:
10+
using: composite
11+
steps:
12+
- name: Set application version
13+
shell: bash
14+
run: ./.github/actions/scripts/set-version.sh ${{ inputs.version }}

0 commit comments

Comments
 (0)