-
Notifications
You must be signed in to change notification settings - Fork 0
349 lines (301 loc) · 12.2 KB
/
ci.yml
File metadata and controls
349 lines (301 loc) · 12.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
name: Test & Build
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [20.x]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Resolve package version
id: package-version
run: |
PACKAGE_VERSION="$(node scripts/latest-package-version.js)"
echo "Resolved package: ${PACKAGE_VERSION}"
echo "package=${PACKAGE_VERSION}" >> "$GITHUB_OUTPUT"
- name: Install LibreOffice
run: |
sudo apt-get update
sudo apt-get install -y libreoffice libreoffice-writer libreoffice-java-common default-jre --no-install-recommends
soffice --version
- name: Run linter
run: npm run lint
continue-on-error: true
- name: Run unit tests
run: npm test
env:
CI: true
LOG_LEVEL: error
# JWT credentials for auth-specific tests
SF_DOMAIN: ${{ secrets.SF_DOMAIN }}
SF_USERNAME: ${{ secrets.SF_USERNAME }}
SF_CLIENT_ID: ${{ secrets.SF_CLIENT_ID }}
SF_PRIVATE_KEY: ${{ secrets.SF_PRIVATE_KEY }}
# Poller configs (using defaults)
# Note: Poller auto-starts but won't process anything without a scratch org
POLLER_INTERVAL_MS: 15000
POLLER_BATCH_SIZE: 20
- name: Setup scratch org for integration tests
id: setup-scratch-org
if: env.DEVHUB_SFDX_AUTH_URL != ''
run: |
echo "📦 Setting up scratch org for integration tests..."
# Install Salesforce CLI if not present
if ! command -v sf &> /dev/null; then
npm install -g @salesforce/cli
fi
# Authenticate to Dev Hub
echo "${{ secrets.SFDX_AUTH_URL }}" > devhub_auth.txt
sf org login sfdx-url --sfdx-url-file devhub_auth.txt --set-default-dev-hub --alias DevHub
rm devhub_auth.txt
# Create scratch org for tests
sf org create scratch \
--definition-file config/project-scratch-def.json \
--alias ci-test-org \
--set-default \
--duration-days 1 \
--wait 10
# Get scratch org auth URL
SCRATCH_ORG_AUTH_URL=$(sf org display --verbose --json --target-org ci-test-org | jq -r '.result.sfdxAuthUrl')
echo "scratch_org_auth_url=$SCRATCH_ORG_AUTH_URL" >> $GITHUB_OUTPUT
# Install package metadata exactly as subscribers receive it.
echo "📦 Installing Docgen unlocked package: ${DOCGEN_PACKAGE_VERSION}"
sf package install \
--package "${DOCGEN_PACKAGE_VERSION}" \
--target-org ci-test-org \
--wait 20 \
--publish-wait 20 \
--apex-compile package \
--no-prompt
# Deploy only scratch-org supplemental metadata.
# Do not deploy force-app/unpackaged/default/connectedApps in CI.
echo "📤 Deploying supported-object custom metadata..."
sf project deploy start \
--source-dir force-app/unpackaged/default/customMetadata \
--target-org ci-test-org \
--wait 10
echo "📤 Deploying test metadata..."
sf project deploy start \
--source-dir force-app/test \
--target-org ci-test-org \
--wait 10
# Assign permission set to user
echo "🔐 Assigning Docgen_User permission set..."
sf org assign permset --name Docgen_User --target-org ci-test-org
echo "✅ Scratch org created and configured successfully"
env:
DEVHUB_SFDX_AUTH_URL: ${{ secrets.SFDX_AUTH_URL }}
DOCGEN_PACKAGE_VERSION: ${{ steps.package-version.outputs.package }}
continue-on-error: true
- name: Run integration tests
run: |
echo "Running Salesforce Integration Tests..."
# Check for either JWT credentials or scratch org auth URL
if [ -n "${{ secrets.SF_DOMAIN }}" ] && [ -n "${{ secrets.SF_USERNAME }}" ] && [ -n "${{ secrets.SF_CLIENT_ID }}" ] && [ -n "${{ secrets.SF_PRIVATE_KEY }}" ]; then
echo "✅ JWT credentials configured - running integration tests with JWT auth"
npm run test:integration
elif [ -n "${{ steps.setup-scratch-org.outputs.scratch_org_auth_url }}" ]; then
echo "✅ Scratch org configured - running integration tests with SFDX auth"
export SFDX_AUTH_URL="${{ steps.setup-scratch-org.outputs.scratch_org_auth_url }}"
npm run test:integration
else
echo "⚠️ No Salesforce credentials configured - skipping integration tests"
echo "To enable integration tests, configure either:"
echo " JWT Auth: SF_DOMAIN, SF_USERNAME, SF_CLIENT_ID, SF_PRIVATE_KEY"
echo " OR Dev Hub: SFDX_AUTH_URL (for scratch org creation)"
fi
env:
CI: true
# JWT credentials (for JWT auth tests)
SF_DOMAIN: ${{ secrets.SF_DOMAIN }}
SF_USERNAME: ${{ secrets.SF_USERNAME }}
SF_CLIENT_ID: ${{ secrets.SF_CLIENT_ID }}
SF_PRIVATE_KEY: ${{ secrets.SF_PRIVATE_KEY }}
continue-on-error: true
- name: Run tests with coverage
run: |
# Set scratch org auth URL if available
if [ -n "${{ steps.setup-scratch-org.outputs.scratch_org_auth_url }}" ]; then
export SFDX_AUTH_URL="${{ steps.setup-scratch-org.outputs.scratch_org_auth_url }}"
fi
npm run test:coverage
env:
CI: true
LOG_LEVEL: error
# JWT credentials for auth-specific tests
SF_DOMAIN: ${{ secrets.SF_DOMAIN }}
SF_USERNAME: ${{ secrets.SF_USERNAME }}
SF_CLIENT_ID: ${{ secrets.SF_CLIENT_ID }}
SF_PRIVATE_KEY: ${{ secrets.SF_PRIVATE_KEY }}
- name: Cleanup scratch org
if: always() && steps.setup-scratch-org.outputs.scratch_org_auth_url != ''
run: |
sf org delete scratch --target-org ci-test-org --no-prompt || true
continue-on-error: true
- name: Upload coverage reports
uses: actions/upload-artifact@v4
if: always()
with:
name: coverage-reports
path: |
coverage/
!coverage/tmp/
retention-days: 30
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
if: always()
with:
files: ./coverage/coverage-final.json
flags: nodejs
fail_ci_if_error: false
verbose: true
continue-on-error: true
- name: Comment coverage summary on PR
uses: romeovs/lcov-reporter-action@v0.3.1
if: github.event_name == 'pull_request'
with:
lcov-file: ./coverage/lcov.info
github-token: ${{ secrets.GITHUB_TOKEN }}
continue-on-error: true
- name: Type check
run: npm run typecheck
- name: Build TypeScript
run: npm run build
- name: Check build artifacts
run: |
if [ ! -d "dist" ]; then
echo "Build failed: dist directory not found"
exit 1
fi
if [ ! -f "dist/server.js" ]; then
echo "Build failed: dist/server.js not found"
exit 1
fi
echo "Build successful: dist/server.js exists"
- name: Validate Dockerfile
run: |
echo "🐳 Validating Dockerfile..."
docker build --target builder -t docgen-api:ci-test .
echo "✅ Dockerfile validation successful"
salesforce:
name: Salesforce Validation
runs-on: ubuntu-latest
env:
SFDX_AUTH_URL: ${{ secrets.SFDX_AUTH_URL }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check Salesforce package version created
if: github.event_name == 'pull_request'
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.sha }}
run: node scripts/check-package-version-created.js
- name: Resolve package version
id: package-version
run: |
PACKAGE_VERSION="$(node scripts/latest-package-version.js)"
echo "Resolved package: ${PACKAGE_VERSION}"
echo "package=${PACKAGE_VERSION}" >> "$GITHUB_OUTPUT"
- name: Install Salesforce CLI
run: |
npm install -g @salesforce/cli
sf version
- name: Authorize Dev Hub
if: env.SFDX_AUTH_URL != ''
run: |
echo "${{ secrets.SFDX_AUTH_URL }}" > auth.txt
sf org login sfdx-url --sfdx-url-file auth.txt --set-default-dev-hub --alias DevHub
rm auth.txt
- name: Create Scratch Org
if: env.SFDX_AUTH_URL != ''
run: |
sf org create scratch --definition-file config/project-scratch-def.json --alias ciorg --set-default --duration-days 1 --wait 10
- name: Install package in Scratch Org
if: env.SFDX_AUTH_URL != ''
env:
DOCGEN_PACKAGE_VERSION: ${{ steps.package-version.outputs.package }}
run: |
sf package install \
--package "${DOCGEN_PACKAGE_VERSION}" \
--target-org ciorg \
--wait 20 \
--publish-wait 20 \
--apex-compile package \
--no-prompt
- name: Deploy supplemental metadata to Scratch Org
if: env.SFDX_AUTH_URL != ''
run: |
# Deploy custom metadata records and test-only metadata without connected apps.
sf project deploy start \
--source-dir force-app/unpackaged/default/customMetadata \
--target-org ciorg \
--wait 10
sf project deploy start \
--source-dir force-app/test \
--target-org ciorg \
--wait 10
- name: Run Apex tests with coverage
if: env.SFDX_AUTH_URL != ''
run: |
sf apex run test --test-level RunLocalTests --code-coverage --result-format json --output-dir coverage-apex --target-org ciorg --wait 10
sf apex run test --test-level RunLocalTests --code-coverage --result-format human --target-org ciorg --wait 10 > apex-test-results.txt
cat apex-test-results.txt
- name: Upload Apex test results
uses: actions/upload-artifact@v4
if: always() && env.SFDX_AUTH_URL != ''
with:
name: apex-test-results
path: apex-test-results.txt
retention-days: 30
- name: Install coverage transformer plugin
if: env.SFDX_AUTH_URL != ''
run: |
echo "y" | sf plugins install apex-code-coverage-transformer
- name: Transform Apex coverage to Cobertura
if: env.SFDX_AUTH_URL != ''
run: |
sf acc-transformer transform \
-j coverage-apex/test-result-codecoverage.json \
-r coverage-apex/cobertura.xml \
-f cobertura
- name: Upload Salesforce coverage to Codecov
uses: codecov/codecov-action@v4
if: env.SFDX_AUTH_URL != ''
with:
files: ./coverage-apex/cobertura.xml
flags: salesforce
fail_ci_if_error: false
verbose: true
continue-on-error: true
- name: Delete Scratch Org
if: always() && env.SFDX_AUTH_URL != ''
run: |
sf org delete scratch --target-org ciorg --no-prompt
- name: Skip Salesforce validation (no Dev Hub configured)
if: env.SFDX_AUTH_URL == ''
run: |
echo "⚠️ Salesforce validation skipped: SFDX_AUTH_URL secret not configured"
echo "To enable Salesforce CI validation:"
echo "1. Authenticate to your Dev Hub org: sf org login web --set-default-dev-hub --alias DevHub"
echo "2. Generate auth URL: sf org display --verbose --target-org DevHub"
echo "3. Add SFDX_AUTH_URL as a GitHub secret with the Sfdx Auth Url value"