Skip to content

Commit 4e89527

Browse files
committed
Keep delivery policy checks self-contained
1 parent 74b2e99 commit 4e89527

2 files changed

Lines changed: 149 additions & 3 deletions

File tree

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: OpenSearch Contract
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
environment:
7+
description: Protected GitHub environment containing the OpenSearch contract-test secrets
8+
required: true
9+
type: environment
10+
11+
permissions:
12+
contents: read
13+
14+
concurrency:
15+
group: search-api-opensearch-contract-${{ inputs.environment }}
16+
cancel-in-progress: false
17+
18+
jobs:
19+
contract:
20+
name: Read-only OpenSearch Contract
21+
if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main'
22+
runs-on: ubuntu-latest
23+
timeout-minutes: 15
24+
environment: ${{ inputs.environment }}
25+
26+
env:
27+
NODE_ENV: production
28+
NODE_CONFIG_ENV: prod
29+
30+
steps:
31+
- name: Check out repository
32+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
33+
34+
- name: Set up Node.js
35+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
36+
with:
37+
node-version: 24.14.1
38+
cache: npm
39+
40+
- name: Install production dependencies
41+
run: npm ci --omit=dev
42+
43+
- name: Run read-only contract checks
44+
run: npm run test:opensearch-contract
45+
env:
46+
OpenSearchDomainEndpoint: ${{ secrets.OPENSEARCH_DOMAIN_ENDPOINT }}
47+
OpenSearchCveIndex: ${{ secrets.OPENSEARCH_CVE_INDEX }}
48+
OpenSearchAllowUnknownSslCerts: ${{ vars.OPENSEARCH_ALLOW_UNKNOWN_SSL_CERTS || 'false' }}

‎.github/workflows/quality.yml‎

Lines changed: 101 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,47 @@ name: Search API Quality
22

33
on:
44
pull_request:
5+
push:
6+
branches:
7+
- dev
8+
- main
9+
merge_group:
510

611
permissions:
712
contents: read
813

914
concurrency:
10-
group: search-api-quality-${{ github.event.pull_request.number }}
15+
group: search-api-quality-${{ github.event.pull_request.number || github.ref }}
1116
cancel-in-progress: true
1217

1318
jobs:
19+
dependency-review:
20+
name: Dependency Review
21+
if: github.event_name == 'pull_request'
22+
runs-on: ubuntu-latest
23+
timeout-minutes: 10
24+
25+
steps:
26+
- name: Check out repository
27+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
28+
29+
- name: Review dependency changes
30+
uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0
31+
with:
32+
fail-on-severity: high
33+
fail-on-scopes: runtime, development
34+
1435
quality:
1536
name: Search API Quality
1637
runs-on: ubuntu-latest
1738
timeout-minutes: 15
1839

1940
steps:
2041
- name: Check out repository
21-
uses: actions/checkout@v4
42+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
2243

2344
- name: Set up Node.js
24-
uses: actions/setup-node@v4
45+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
2546
with:
2647
node-version: 24.14.1
2748
cache: npm
@@ -31,3 +52,80 @@ jobs:
3152

3253
- name: Run quality checks
3354
run: npm run quality
55+
56+
container:
57+
name: Runtime Container
58+
runs-on: ubuntu-latest
59+
timeout-minutes: 15
60+
61+
steps:
62+
- name: Check out repository
63+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
64+
65+
- name: Build production image
66+
run: docker build --tag cve-search-api:pr .
67+
68+
- name: Report all high and critical image vulnerabilities
69+
continue-on-error: true
70+
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
71+
with:
72+
scan-type: image
73+
image-ref: cve-search-api:pr
74+
format: table
75+
exit-code: 0
76+
ignore-unfixed: false
77+
severity: CRITICAL,HIGH
78+
scanners: vuln
79+
trivyignores: /dev/null
80+
version: v0.69.3
81+
82+
- name: Enforce fixable high and critical image vulnerabilities
83+
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
84+
with:
85+
scan-type: image
86+
image-ref: cve-search-api:pr
87+
format: table
88+
exit-code: 1
89+
ignore-unfixed: true
90+
severity: CRITICAL,HIGH
91+
scanners: vuln
92+
trivyignores: .trivyignore
93+
version: v0.69.3
94+
95+
- name: Start production image
96+
run: |
97+
docker run --detach \
98+
--name cve-search-api-pr \
99+
--publish 4100:3000 \
100+
--env NODE_CONFIG_ENV=prod \
101+
--env OpenSearchDomainEndpoint=https://search.example.com \
102+
--env OpenSearchCveIndex=cves \
103+
cve-search-api:pr
104+
105+
- name: Validate runtime image
106+
run: |
107+
for attempt in $(seq 1 30); do
108+
if curl --fail --silent --show-error http://127.0.0.1:4100/api/health-check; then
109+
break
110+
fi
111+
if [ "$attempt" -eq 30 ]; then
112+
exit 1
113+
fi
114+
sleep 1
115+
done
116+
117+
curl --fail --silent --show-error http://127.0.0.1:4100/api-docs/openapi.json \
118+
| jq --exit-status \
119+
'.openapi == "3.0.2" and .info.title == "CVE Search API"' \
120+
> /dev/null
121+
122+
test "$(docker image inspect cve-search-api:pr --format '{{.Config.User}}')" = "65532:65532"
123+
test "$(docker image inspect cve-search-api:pr --format '{{json .Config.Cmd}}')" = '["server.js"]'
124+
125+
- name: Capture container logs
126+
if: always()
127+
run: docker logs cve-search-api-pr || true
128+
129+
- name: Remove test container
130+
if: always()
131+
run: docker rm --force cve-search-api-pr || true

0 commit comments

Comments
 (0)