Skip to content

Commit f321972

Browse files
CLOUDP-290416: Fix and refactor IPA metrics release workflow (#387)
1 parent fc9b5b6 commit f321972

File tree

6 files changed

+91
-42
lines changed

6 files changed

+91
-42
lines changed

.github/workflows/release-IPA-metrics.yml

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,11 @@ permissions:
2727
issues: write
2828

2929
jobs:
30-
release-IPA-metrics:
30+
pre-IPA-metrics-release-checks:
31+
name: IPA Metrics Release Pre-Checks
3132
runs-on: ubuntu-latest
33+
outputs:
34+
should_run_release: ${{ steps.get_previous_status.outputs.result }}
3235
steps:
3336
- name: Checkout
3437
uses: actions/checkout@v4
@@ -39,43 +42,46 @@ jobs:
3942
with:
4043
github-token: ${{ secrets.api_bot_pat }}
4144
script: |
42-
const script = require('tools/spectral/ipa/metrics/scripts/getShouldRunMetricsRelease.js')
43-
const shouldRunRelease = await getShouldRunMetricsRelease({github, context})
45+
const { default: getShouldRunMetricsRelease } = await import('${{ github.workspace }}/tools/spectral/ipa/metrics/scripts/getShouldRunMetricsRelease.js')
46+
const shouldRunRelease = await getShouldRunMetricsRelease({github, context}).catch((error) => {
47+
console.error(error.message);
48+
process.exit(1)
49+
})
4450
return shouldRunRelease
4551
46-
- name: Skip Metric Collection Job
47-
if: ${{steps.get_previous_status.outputs.result == 'false' }}
48-
run: echo "Skipping IPA metrics release!"
52+
release-IPA-metrics:
53+
name: Release IPA Validation Metrics
54+
needs: [pre-IPA-metrics-release-checks]
55+
if: ${{ needs.pre-IPA-metrics-release-checks.outputs.should_run_release == 'true' }}
56+
runs-on: ubuntu-latest
57+
steps:
58+
- name: Checkout
59+
uses: actions/checkout@v4
4960

5061
- name: Setup Node
51-
if: ${{steps.get_previous_status.outputs.result == 'true' }}
5262
uses: actions/setup-node@v4
5363
with:
5464
node-version: '20.x'
5565
cache: 'npm'
5666

5767
- name: Install npm dependencies
58-
if: ${{steps.get_previous_status.outputs.result == 'true' }}
5968
run: npm install
6069

61-
- name: Download openapi-foas
62-
if: ${{steps.get_previous_status.outputs.result == 'true' }}
63-
uses: actions/download-artifact@v4
64-
with:
65-
name: openapi-foas-dev # TODO: Change to passed input env
66-
github-token: ${{ secrets.api_bot_pat }}
67-
run-id: ${{ github.run_id }}
70+
# - name: Download openapi-foas
71+
# uses: actions/download-artifact@v4
72+
# with:
73+
# name: openapi-foas-dev # TODO: Change to passed input env
74+
# github-token: ${{ secrets.api_bot_pat }}
75+
# run-id: ${{ github.run_id }}
6876

6977
- name: Run Metric Collection Job
70-
if: ${{steps.get_previous_status.outputs.result == 'true' }}
7178
working-directory: ./tools/spectral/ipa/metrics/scripts
72-
run: node runMetricCollection.js ../../../../../openapi-foas.json
79+
run: node runMetricCollection.js ../../../../../openapi/v2.json # TODO: Change to foas from above
7380

7481
- name: Dump Metric Collection Job Data to S3
75-
if: ${{steps.get_previous_status.outputs.result == 'true' }}
7682
env:
7783
AWS_ACCESS_KEY_ID: ${{ secrets.IPA_S3_BUCKET_DW_STAGING_USERNAME }} # TODO: Change to passed secret
7884
AWS_SECRET_ACCESS_KEY: ${{ secrets.IPA_S3_BUCKET_DW_STAGING_PASSWORD }} # TODO: Change to passed secret
7985
S3_BUCKET_PREFIX: ${{ secrets.IPA_S3_BUCKET_DW_STAGING_PREFIX }} # TODO: Change to passed secret
8086
working-directory: ./tools/spectral/ipa/metrics/scripts
81-
run: node dataDump.js ../../../../../openapi-foas.json
87+
run: node dataDump.js

tools/spectral/ipa/metrics/metricS3Upload.js

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,33 @@ import { getS3Client, getS3FilePath } from './utils/dataDumpUtils.js';
1010
* @param filePath file path to the metrics collection results, uses config.js by default
1111
*/
1212
export async function uploadMetricCollectionDataToS3(filePath = config.defaultMetricCollectionResultsFilePath) {
13-
const client = getS3Client();
14-
const formattedDate = new Date().toISOString().split('T')[0];
13+
console.log('Loading metrics collection data from', filePath);
1514
const metricsCollectionData = JSON.parse(fs.readFileSync(filePath, 'utf8'));
16-
const table = tableFromJSON(metricsCollectionData);
15+
if (metricsCollectionData === undefined || metricsCollectionData.length === 0) {
16+
throw new Error('Loaded metrics collection data is empty');
17+
}
1718

18-
const s3fileProps = getS3FilePath();
19-
const command = new PutObjectCommand({
20-
Bucket: s3fileProps.bucketName,
21-
Key: path.join(s3fileProps.key, formattedDate, 'metric-collection-results.parquet'),
22-
Body: tableToIPC(table, 'stream'),
23-
});
19+
const table = tableFromJSON(metricsCollectionData);
20+
if (table === undefined) {
21+
throw new Error('Unable to transform metrics collection data to table');
22+
}
2423

2524
try {
26-
const response = await client.send(command);
27-
console.log(response);
25+
console.log('Creating S3 Client...');
26+
const client = getS3Client();
27+
28+
console.log('Getting S3 file path...');
29+
const s3fileProps = getS3FilePath();
30+
const formattedDate = new Date().toISOString().split('T')[0];
31+
32+
const command = new PutObjectCommand({
33+
Bucket: s3fileProps.bucketName,
34+
Key: path.join(s3fileProps.key, formattedDate, 'metric-collection-results.parquet'),
35+
Body: tableToIPC(table, 'stream'),
36+
});
37+
38+
console.log('Dumping data to S3...');
39+
return await client.send(command);
2840
} catch (caught) {
2941
if (caught instanceof S3ServiceException && caught.name === 'EntityTooLarge') {
3042
console.error(

tools/spectral/ipa/metrics/scripts/dataDump.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@ import { uploadMetricCollectionDataToS3 } from '../metricS3Upload.js';
33
const args = process.argv.slice(2);
44
const filePath = args[0];
55

6-
uploadMetricCollectionDataToS3(filePath)
7-
.then(() => console.log('Data dump to S3 completed successfully.'))
8-
.catch((error) => console.error(error.message));
6+
const response = await uploadMetricCollectionDataToS3(filePath).catch((error) => {
7+
console.error(error.message);
8+
process.exit(1);
9+
});
10+
11+
if (!response) {
12+
console.error('PutObject response is undefined');
13+
process.exit(1);
14+
}
15+
16+
console.log('Data dump to S3 completed successfully.');
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
11
// Used in .github/workflows/release-IPA-metrics.yml
22
export default async function getShouldRunMetricsRelease({ github, context }) {
3-
const response = await github.actions.listWorkflowRuns({
3+
const response = await github.rest.actions.listWorkflowRuns({
44
owner: context.repo.owner,
55
repo: context.repo.repo,
6-
workflow_id: context.workflow,
6+
workflow_id: 'release-IPA-metrics.yml',
77
per_page: 2,
88
page: 1,
99
});
1010

11-
if (response === undefined) {
12-
return true;
11+
if (!response || !response.data) {
12+
throw Error('listWorkFlowRuns response is empty');
1313
}
1414

15-
const { data: runs } = response;
15+
const { workflow_runs: runs } = response.data;
1616

1717
if (runs === undefined || runs.length === 0) {
18-
return true;
18+
throw Error('response.data.workflow_runs is empty');
1919
}
2020

21-
const previousStatus = runs[1].status;
21+
const previousResult = runs[1].conclusion;
2222

2323
const lastRunDate = new Date(runs[1].created_at);
2424
const today = new Date();
2525

26-
return previousStatus === 'failure' || today.toDateString() !== lastRunDate.toDateString();
26+
return previousResult === 'failure' || today.toDateString() !== lastRunDate.toDateString();
2727
}

tools/spectral/ipa/metrics/scripts/runMetricCollection.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,28 @@ if (!fs.existsSync(config.defaultOutputsDir)) {
1313
console.log(`Output directory created successfully`);
1414
}
1515

16-
const result = spawnSync('spectral', ['lint', config.defaultOasFilePath, '--ruleset', config.defaultRulesetFilePath]);
16+
if (!fs.existsSync(config.defaultRulesetFilePath)) {
17+
console.error('Could not find ruleset file path', config.defaultRulesetFilePath);
18+
process.exit(1);
19+
}
20+
21+
if (!oasFilePath && !fs.existsSync(config.defaultOasFilePath)) {
22+
console.error('Could not find default OAS file path', config.defaultOasFilePath);
23+
process.exit(1);
24+
}
25+
26+
if (oasFilePath && !fs.existsSync(oasFilePath)) {
27+
console.error('Could not find OAS file path', oasFilePath);
28+
process.exit(1);
29+
}
30+
31+
const result = spawnSync('npx', [
32+
'spectral',
33+
'lint',
34+
oasFilePath ? oasFilePath : config.defaultOasFilePath,
35+
'--ruleset',
36+
config.defaultRulesetFilePath,
37+
]);
1738

1839
if (result.error) {
1940
console.error('Error running Spectral lint:', result.error);

tools/spectral/ipa/metrics/utils/dataDumpUtils.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import dotenv from 'dotenv';
33
import { S3Client } from '@aws-sdk/client-s3';
44

55
function loadS3Config() {
6+
console.log('Loading S3 config...');
7+
68
if (existsSync('.env') && !process.env.S3_BUCKET_PREFIX) {
79
dotenv.config();
810
}

0 commit comments

Comments
 (0)