Skip to content

Commit f3f13a9

Browse files
Merge pull request #2551 from newrelic/feature/validation-workflow
New validation/release workflow
2 parents c616b1d + b413c6f commit f3f13a9

File tree

9 files changed

+166
-29
lines changed

9 files changed

+166
-29
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: Build and Validate Artifact
2+
description: Reusable action to build and validate the component artifact
3+
inputs:
4+
output-artifact:
5+
description: 'If provided, the action will output the artifact to the build directory'
6+
required: false
7+
8+
runs:
9+
using: composite
10+
steps:
11+
- name: Add data source ids to schema
12+
shell: bash
13+
run: |
14+
cd utils && yarn add-datasource-ids
15+
16+
- name: Build & Validate Artifact
17+
shell: bash
18+
id: build-validate-artifact
19+
run: |
20+
cd utils && yarn build-validate-quickstart-artifact ${{ inputs.output-artifact && '--output-artifact' || '' }}
21+
22+
- name: Debugging output
23+
shell: bash
24+
if: ${{ runner.debug }}
25+
run: ls -la utils/build
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
name: Bump version tag
2+
description: Bumps the version tag based on the latest version
3+
outputs:
4+
tag:
5+
description: The new tag prefixed with `v`
6+
value: ${{ steps.versions.outputs.v-version }}
7+
runs:
8+
using: composite
9+
steps:
10+
- name: Get next version
11+
uses: reecetech/version-increment@a5d65984a6c6e8bbc30ece69d53d96e40736f24c
12+
id: versions
13+
with:
14+
scheme: semver
15+
increment: minor
16+
use_api: true

.github/workflows/pr-checks.yml

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
name: Validate PR Artifact
2+
3+
on:
4+
pull_request:
5+
6+
jobs:
7+
validate:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- name: Checkout repository
11+
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
12+
with:
13+
ref: ${{ github.sha }}
14+
- name: Setup workspace
15+
uses: "./.github/actions/bootstrap"
16+
- name: Validate PR Artifact
17+
uses: "./.github/actions/build-validate-artifact"
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# This workflow runs when a tag is created with the `v` prefix or a push
2+
# to main occurs. It runs our validation script, outputs the artifact,
3+
# creates a new tag, Github release, and uploads/associates the artifact with the release.
4+
5+
name: Release artifact
6+
on:
7+
push:
8+
branches:
9+
- main
10+
tags:
11+
- 'v*'
12+
13+
# Permissions for attestation
14+
permissions:
15+
id-token: write
16+
contents: write
17+
attestations: write
18+
19+
jobs:
20+
release:
21+
runs-on: ubuntu-latest
22+
steps:
23+
- name: Checkout repository
24+
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
25+
with:
26+
ref: ${{ github.ref }}
27+
- name: Setup workspace
28+
uses: "./.github/actions/bootstrap"
29+
- name: Validate and generate artifact
30+
uses: "./.github/actions/build-validate-artifact"
31+
with:
32+
output-artifact: 'true'
33+
- name: Attest artifact
34+
uses: actions/attest-build-provenance@1c608d11d69870c2092266b3f9a6f3abbf17002c
35+
with:
36+
subject-path: utils/build/*
37+
- name: Create new release tag
38+
# Only run if this is a branch push (we'll need a new tag)
39+
if: ${{ startsWith(github.ref, 'refs/heads') }}
40+
id: version
41+
uses: "./.github/actions/bump-version-tag"
42+
- name: Create release
43+
uses: softprops/action-gh-release@c062e08bd532815e2082a85e87e3ef29c3e6d191
44+
with:
45+
files: utils/build/*
46+
fail_on_unmatched_files: true
47+
make_latest: true
48+
# If we have a tag output from the previous step, use that as the tag
49+
# name, otherwise use the current ref which should be the tag.
50+
tag_name: ${{ steps.version.outputs.tag || github.ref }}

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
utils/node_modules
22
utils/newrelic_agent.log
3+
utils/build
34

45
# IDE files
56
.DS_Store
@@ -17,4 +18,4 @@ snapshots/
1718
yarn.lock
1819
.yarn-integrity
1920
yarn-error.log
20-
utils/yarn-error.log
21+
utils/yarn-error.log

utils/build-validate-quickstart-artifact.ts

+40-19
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import Dashboard, { DashboardConfig } from "./lib/Dashboard";
99
import Ajv, { type ErrorObject } from 'ajv';
1010
import { QuickstartConfig, QuickstartConfigAlert } from './types/QuickstartConfig';
1111
import { DataSourceConfig } from './types/DataSourceConfig';
12+
import { passedProcessArguments } from './lib/helpers';
1213

1314
type ArtifactSchema = Record<string, unknown>;
1415

@@ -74,7 +75,7 @@ export const validateArtifact = (schema: ArtifactSchema, artifact: Artifact): Er
7475
return ajv.errors ?? [];
7576
}
7677

77-
const main = () => {
78+
const main = (shouldOutputArtifact: boolean = false) => {
7879
const schema = getSchema('./schema/artifact.json');
7980
const components = getArtifactComponents();
8081
const dataSourceIds = getDataSourceIds('./schema/core-datasource-ids.json', components.dataSources);
@@ -88,6 +89,25 @@ const main = () => {
8889
}
8990

9091
console.log('[*] Validation succeeded');
92+
93+
if (shouldOutputArtifact) {
94+
outputArtifact(artifact);
95+
}
96+
}
97+
98+
const outputArtifact = (artifact: Artifact) => {
99+
console.log('[*] Outputting the artifact');
100+
try {
101+
fs.mkdirSync('./build', { recursive: true });
102+
103+
// Dump the artifact to artifact.json
104+
fs.writeFileSync('./build/artifact.json', JSON.stringify(artifact));
105+
// Copy the schema to schema.json
106+
fs.copyFileSync('./schema/artifact.json', './build/schema.json');
107+
} catch (e) {
108+
console.error('Error writing artifact to file:', e);
109+
process.exit(1);
110+
}
91111
}
92112

93113
const getInvalidItems = (errors: ErrorObject[], artifact: ArtifactSchema): InvalidItem[] => {
@@ -108,25 +128,26 @@ const getInvalidItems = (errors: ErrorObject[], artifact: ArtifactSchema): Inval
108128
}
109129

110130
const printErrors = (invalidItems: InvalidItem[]): void => {
111-
console.error('*** Validation failed. See errors below. ***');
112-
console.error('--------------------------------------------');
113-
114-
invalidItems.forEach(({ value, component, error }, idx) => {
115-
console.error(`Error #${idx + 1}:`, error);
116-
console.error('');
117-
console.error('Received value:', value);
118-
119-
console.error('');
120-
if (component !== value) {
121-
console.error('Invalid component:', component);
122-
}
123-
124-
if (idx < invalidItems.length - 1) {
125-
console.error('************************************');
126-
}
127-
});
131+
console.error('*** Validation failed. See errors below. ***');
132+
console.error('--------------------------------------------');
133+
134+
invalidItems.forEach(({ value, component, error }, idx) => {
135+
console.error(`Error #${idx + 1}:`, error);
136+
console.error('');
137+
console.error('Received value:', value);
138+
139+
console.error('');
140+
if (component !== value) {
141+
console.error('Invalid component:', component);
142+
}
143+
144+
if (idx < invalidItems.length - 1) {
145+
console.error('************************************');
146+
}
147+
});
128148
}
129149

130150
if (require.main === module) {
131-
main();
151+
const shouldOutputArtifact = passedProcessArguments().includes('--output-artifact');
152+
main(shouldOutputArtifact);
132153
}

utils/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"validate-quickstart-data-sources": "ts-node validate-quickstart-data-sources.ts",
99
"create-validate-data-sources": "ts-node create-validate-data-sources.ts",
1010
"create-validate-pr-quickstarts": "ts-node create_validate_pr_quickstarts.ts",
11+
"build-validate-quickstart-artifact": "ts-node build-validate-quickstart-artifact.ts",
1112
"check-dashboard-name-uniqueness": "ts-node check_dashboard_name_uniqueness.ts",
1213
"test": "jest -i",
1314
"check-quickstart-uniqueness": "ts-node check_quickstart_uniqueness.ts",

utils/schema/add-datasource-ids.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const CORE_DATASOURCE_IDS_PATH = './core-datasource-ids.json';
1010
const DATASOURCE_BASE_PATH = '../../';
1111

1212
type ArtifactSchema = {
13-
properties: {
13+
definitions: {
1414
dataSourceIds: {
1515
enum: string[];
1616
};
@@ -50,8 +50,8 @@ const updateSchema = (
5050
): ArtifactSchema => {
5151
return {
5252
...schema,
53-
properties: {
54-
...schema.properties,
53+
definitions: {
54+
...schema.definitions,
5555
dataSourceIds: { enum: ids },
5656
},
5757
};

utils/schema/artifact.json

+12-6
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
"items": { "$ref": "#/definitions/dashboard" }
2121
},
2222
"dataSourceIds": {
23-
"type": "array", "items": { "type": "string" }
23+
"type": "array",
24+
"items": { "$ref": "#/definitions/dataSourceIds" }
2425
}
2526
},
2627
"required": [
@@ -41,7 +42,8 @@
4142
"summary": { "type": "string" },
4243
"title": { "type": "string" },
4344
"authors": {
44-
"type": "array", "items": { "type": "string" }
45+
"type": "array",
46+
"items": { "type": "string" }
4547
},
4648
"documentation": {
4749
"type": "array",
@@ -59,17 +61,21 @@
5961
"level": { "enum": ["New Relic", "Community", "Verified"] },
6062
"icon": { "type": "string" },
6163
"keywords": {
62-
"type": "array", "items": { "type": "string" }
64+
"type": "array",
65+
"items": { "type": "string" }
6366
},
6467
"slug": { "type": "string" },
6568
"alertPolicies": {
66-
"type": "array", "items": { "type": "string" }
69+
"type": "array",
70+
"items": { "type": "string" }
6771
},
6872
"dashboards": {
69-
"type": "array", "items": { "type": "string" }
73+
"type": "array",
74+
"items": { "type": "string" }
7075
},
7176
"dataSourceIds": {
72-
"type": "array", "items": { "type": "string" }
77+
"type": "array",
78+
"items": { "$ref": "#/definitions/dataSourceIds" }
7379
}
7480
},
7581
"required": [

0 commit comments

Comments
 (0)