Skip to content

Commit c45181b

Browse files
Merge pull request #2924 from anthony-c-martin/main
Support batching in GitHub Actions
2 parents ba57c9c + d3eeb99 commit c45181b

File tree

4 files changed

+122
-172
lines changed

4 files changed

+122
-172
lines changed
Lines changed: 59 additions & 168 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
name: Generate Schemas batch
1+
name: Generate Schemas Batch
22

33
on:
44
schedule:
5-
- cron: '0 1 * * 3'
5+
- cron: '45 5 * * SUN'
66
workflow_dispatch:
77
inputs:
88
api_specs_ref:
@@ -11,215 +11,106 @@ on:
1111
default: 'main'
1212

1313
env:
14-
SUMMARY_LOG_DIR: /tmp/summary
15-
SUMMARY_LOG_PATH: /tmp/summary/summary.log
16-
SUMMARY_LOG_ARTIFACT_NAME: summary-log
17-
AUTOGENERATE_BRANCH_NAME: autogenerate
18-
TEMP_AUTOGENERATE_BRANCH_NAME: autogenerate_tmp
19-
AUTHOR: ${{ github.actor }}
20-
AUTHOR_EMAIL: ${{ github.actor }}@users.noreply.github.com
14+
# This must be kept in sync with the arguments passed to the "batch" matrix
15+
BATCH_COUNT: 20
16+
2117
jobs:
22-
batch-0:
23-
name: Update Schemas Batch 0
18+
generate:
19+
name: Update Schemas Batch ${{ matrix.batch }}
2420
runs-on: ubuntu-latest
21+
strategy:
22+
matrix:
23+
batch: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
2524
steps:
26-
- uses: actions/[email protected]
27-
with:
28-
ref: ${{ env.AUTOGENERATE_BRANCH_NAME }}
29-
30-
- uses: peterjgrainger/[email protected]
31-
env:
32-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
33-
with:
34-
branch: ${{ env.TEMP_AUTOGENERATE_BRANCH_NAME }}
25+
- name: Checkout repo
26+
uses: actions/checkout@v3
3527

3628
- name: Clone azure-rest-api-specs
37-
uses: actions/checkout@v2.3.5
29+
uses: actions/checkout@v3
3830
with:
3931
repository: Azure/azure-rest-api-specs
4032
path: workflow-temp/azure-rest-api-specs
4133
ref: ${{ github.event.inputs.api_specs_ref }}
42-
43-
- name: Install generator npm packages
44-
run: npm ci
45-
working-directory: generator
4634

47-
- name: Create initial log description
48-
run: mkdir -p /tmp/summary
49-
50-
- id: generate
51-
name: Run generator
52-
run: |
53-
npm run generate-all -- --local-path "$GITHUB_WORKSPACE/workflow-temp/azure-rest-api-specs" --summary-log-path $SUMMARY_LOG_PATH --batch-count 4 --batch-index 0
54-
working-directory: generator
55-
56-
- name: Commit changes
57-
uses: EndBug/add-and-commit@v8
35+
- name: Setup Node.js
36+
uses: actions/setup-node@v3
5837
with:
59-
default_author: github_actor
60-
message: 'Autogenerate schemas batch 0'
61-
new_branch: ${{ env.TEMP_AUTOGENERATE_BRANCH_NAME }}
62-
63-
- name: Upload summary log
64-
uses: actions/upload-artifact@v2
65-
with:
66-
name: ${{ env.SUMMARY_LOG_ARTIFACT_NAME }}
67-
path: ${{ env.SUMMARY_LOG_PATH }}
68-
batch-1:
69-
needs: batch-0
70-
name: Update Schemas Batch 1
71-
runs-on: ubuntu-latest
72-
steps:
73-
- uses: actions/[email protected]
74-
with:
75-
ref: ${{ env.TEMP_AUTOGENERATE_BRANCH_NAME }}
76-
77-
- name: Clone azure-rest-api-specs
78-
uses: actions/[email protected]
79-
with:
80-
repository: Azure/azure-rest-api-specs
81-
path: workflow-temp/azure-rest-api-specs
82-
ref: ${{ github.event.inputs.api_specs_ref }}
38+
node-version: 16.x
8339

8440
- name: Install generator npm packages
8541
run: npm ci
8642
working-directory: generator
8743

88-
- name: Download summary log artifact
89-
uses: actions/download-artifact@v2
90-
with:
91-
name: ${{ env.SUMMARY_LOG_ARTIFACT_NAME }}
92-
path: ${{ env.SUMMARY_LOG_DIR }}
93-
94-
- id: generate
95-
name: Run generator
44+
- name: Run generator
9645
run: |
97-
npm run generate-all -- --local-path "$GITHUB_WORKSPACE/workflow-temp/azure-rest-api-specs" --summary-log-path $SUMMARY_LOG_PATH --batch-count 4 --batch-index 1
46+
rm -Rf "$GITHUB_WORKSPACE/schemas"
47+
rm -Rf "$GITHUB_WORKSPACE/summary.log"
48+
mkdir -p "$GITHUB_WORKSPACE/schemas"
49+
50+
npm run generate-all -- \
51+
--local-path "$GITHUB_WORKSPACE/workflow-temp/azure-rest-api-specs" \
52+
--batch-count ${{ env.BATCH_COUNT }} \
53+
--batch-index ${{ matrix.batch }} \
54+
--summary-log-path "$GITHUB_WORKSPACE/summary.log" \
55+
--combine-batch-mode true
9856
working-directory: generator
9957

100-
- name: Commit changes
101-
uses: EndBug/add-and-commit@v8
58+
- name: Upload Schemas
59+
uses: actions/upload-artifact@v3
10260
with:
103-
default_author: github_actor
104-
message: 'Autogenerate schemas batch 1'
105-
new_branch: ${{ env.TEMP_AUTOGENERATE_BRANCH_NAME }}
61+
name: batch-${{ matrix.batch }}-schemas
62+
path: schemas
63+
if-no-files-found: error
10664

10765
- name: Upload summary log
108-
uses: actions/upload-artifact@v2
66+
uses: actions/upload-artifact@v3
10967
with:
110-
name: ${{ env.SUMMARY_LOG_ARTIFACT_NAME }}
111-
path: ${{ env.SUMMARY_LOG_PATH }}
112-
batch-2:
113-
needs: batch-1
114-
name: Update Schemas Batch 2
115-
runs-on: ubuntu-latest
116-
steps:
117-
- uses: actions/[email protected]
118-
with:
119-
ref: ${{ env.TEMP_AUTOGENERATE_BRANCH_NAME }}
68+
name: batch-${{ matrix.batch }}-summary
69+
path: summary.log
70+
if-no-files-found: error
12071

121-
- name: Clone azure-rest-api-specs
122-
uses: actions/[email protected]
123-
with:
124-
repository: Azure/azure-rest-api-specs
125-
path: workflow-temp/azure-rest-api-specs
126-
ref: ${{ github.event.inputs.api_specs_ref }}
127-
128-
- name: Install generator npm packages
129-
run: npm ci
130-
working-directory: generator
131-
132-
- name: Download summary log artifact
133-
uses: actions/download-artifact@v2
134-
with:
135-
name: ${{ env.SUMMARY_LOG_ARTIFACT_NAME }}
136-
path: ${{ env.SUMMARY_LOG_DIR }}
137-
138-
- id: generate
139-
name: Run generator
140-
run: |
141-
npm run generate-all -- --local-path "$GITHUB_WORKSPACE/workflow-temp/azure-rest-api-specs" --summary-log-path $SUMMARY_LOG_PATH --batch-count 4 --batch-index 2
142-
working-directory: generator
143-
144-
- name: Commit changes
145-
uses: EndBug/add-and-commit@v8
146-
with:
147-
default_author: github_actor
148-
message: 'Autogenerate schemas batch 2'
149-
new_branch: ${{ env.TEMP_AUTOGENERATE_BRANCH_NAME }}
150-
151-
- name: Upload summary log
152-
uses: actions/upload-artifact@v2
153-
with:
154-
name: ${{ env.SUMMARY_LOG_ARTIFACT_NAME }}
155-
path: ${{ env.SUMMARY_LOG_PATH }}
156-
batch-3:
157-
needs: batch-2
158-
name: Update Schemas Batch 3
72+
combine:
73+
needs: generate
74+
name: Combine Schema Batches
15975
runs-on: ubuntu-latest
16076
steps:
161-
- uses: actions/[email protected]
77+
- name: Checkout repo
78+
uses: actions/checkout@v3
79+
80+
- name: Download batch results
81+
uses: actions/download-artifact@v3
16282
with:
163-
ref: ${{ env.TEMP_AUTOGENERATE_BRANCH_NAME }}
83+
path: workflow-temp
16484

165-
- name: Clone azure-rest-api-specs
166-
uses: actions/[email protected]
85+
- name: Setup Node.js
86+
uses: actions/setup-node@v3
16787
with:
168-
repository: Azure/azure-rest-api-specs
169-
path: workflow-temp/azure-rest-api-specs
170-
ref: ${{ github.event.inputs.api_specs_ref }}
88+
node-version: 16.x
17189

17290
- name: Install generator npm packages
17391
run: npm ci
17492
working-directory: generator
17593

176-
- name: Download summary log artifact
177-
uses: actions/download-artifact@v2
178-
with:
179-
name: ${{ env.SUMMARY_LOG_ARTIFACT_NAME }}
180-
path: ${{ env.SUMMARY_LOG_DIR }}
181-
182-
- id: generate
183-
name: Run generator
94+
- name: Combine batches
18495
run: |
185-
npm run generate-all -- --local-path "$GITHUB_WORKSPACE/workflow-temp/azure-rest-api-specs" --summary-log-path $SUMMARY_LOG_PATH --batch-count 4 --batch-index 3
186-
187-
summary="$(<$SUMMARY_LOG_PATH)"
188-
summary="${summary//'%'/'%25'}"
189-
summary="${summary//$'\n'/'%0A'}"
190-
summary="${summary//$'\r'/'%0D'}"
191-
echo "::set-output name=summary::$summary"
96+
npm run combine-batches -- \
97+
--input-path "$GITHUB_WORKSPACE/workflow-temp" \
98+
--batch-count ${{ env.BATCH_COUNT }}
19299
working-directory: generator
193100

194-
- id: get_swagger_gh_uri
195-
name: Get GitHub URI for azure-rest-api-specs
196-
run: |
197-
git_sha=`git rev-parse HEAD`
198-
echo "::set-output name=gh_uri::https://github.com/Azure/azure-rest-api-specs/tree/$git_sha"
199-
working-directory: workflow-temp/azure-rest-api-specs
200-
201101
- name: Create Pull Request
202-
uses: peter-evans/create-pull-request@v4.1.3
102+
uses: peter-evans/create-pull-request@v5
203103
with:
204104
committer: GitHub <[email protected]>
205-
author: ${{ env.AUTHOR }} <${{ env.AUTHOR_EMAIL }}>
105+
author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>
206106
signoff: false
207-
branch: main
208-
branch-suffix: short-commit-hash
107+
branch: autogenerate-batch
209108
delete-branch: true
210-
token: ${{ secrets.GITHUB_TOKEN }}
211109
title: |
212-
Update Generated Schemas ${{ github.event.inputs.single_path && format('(single path: {0})', github.event.inputs.single_path) || '' }}
110+
Update Generated Schemas
213111
body: |
214-
Update Generated Schemas ${{ github.event.inputs.single_path && format('(single path: {0})', github.event.inputs.single_path) || '' }}
215-
216-
Generate schemas for ${{ steps.get_swagger_gh_uri.outputs.gh_uri }}
217-
218-
Summary
219-
${{ steps.generate.outputs.summary }}
112+
Update Generated Schemas
220113
commit-message: |
221-
Update Generated Schemas ${{ github.event.inputs.single_path && format('(single path: {0})', github.event.inputs.single_path) || '' }}
222-
223-
Generate schemas for ${{ steps.get_swagger_gh_uri.outputs.gh_uri }}
224-
labels: automerge
114+
Update Generated Schemas
115+
labels: autogenerate
225116
draft: false

generator/cmd/combine-batches.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
import path from 'path';
4+
import { SchemaConfiguration, saveAutoGeneratedSchemaRefs } from '../generate';
5+
import { executeSynchronous, readJsonFile, } from '../utils';
6+
import yargs from 'yargs';
7+
import { flatten, uniq } from 'lodash';
8+
import { cp } from 'fs/promises';
9+
import { schemasBasePath } from '../constants';
10+
11+
const argsConfig = yargs
12+
.strict()
13+
.option('input-path', { type: 'string', desc: 'The path to find batch results' })
14+
.option('batch-count', { type: 'number', desc: 'The total number of batches' });
15+
16+
executeSynchronous(async () => {
17+
const args = await argsConfig.parseAsync();
18+
19+
const inputPath = args['input-path'];
20+
const batchCount = args['batch-count'];
21+
if (!inputPath || !batchCount) {
22+
throw 'Bad input';
23+
}
24+
25+
let schemaConfigs: SchemaConfiguration[] = [];
26+
for (let i = 0; i < batchCount; i++) {
27+
const schemasPath = path.join(inputPath, `batch-${i}-schemas`);
28+
const batchSchemaConfigs: SchemaConfiguration[] = await readJsonFile(`${schemasPath}/schemaconfig.json`);
29+
30+
const relativePaths = uniq(batchSchemaConfigs.map(x => x.relativePath));
31+
for (const relativePath of relativePaths) {
32+
const source = path.join(schemasPath, relativePath);
33+
const dest = path.join(schemasBasePath, relativePath);
34+
35+
console.log(`copying ${source} to ${dest}`);
36+
await cp(source, dest, { force: true });
37+
}
38+
39+
console.log(`schema config for batch ${i}: ${JSON.stringify(batchSchemaConfigs, null, 2)}`);
40+
schemaConfigs = [...schemaConfigs, ...batchSchemaConfigs];
41+
}
42+
43+
await saveAutoGeneratedSchemaRefs(flatten(schemaConfigs));
44+
});

generator/cmd/generateall.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import path from 'path';
1313

1414
import { createWriteStream } from 'fs';
1515
import stripAnsi from 'strip-ansi';
16+
import { schemasBasePath } from '../constants';
1617

1718
const argsConfig = yargs
1819
.strict()
@@ -21,6 +22,7 @@ const argsConfig = yargs
2122
.option('local-path', { type: 'string', desc: 'The local path to the azure-rest-api-specs repo' })
2223
.option('readme-files', { type: 'array', desc: 'The list of readme.md files to generate schemas for' })
2324
.option('output-path', { type: 'string', desc: 'The base path to save schema output' })
25+
.option('combine-batch-mode', { type: 'boolean', desc: 'If true, we rely on the combine-batches command to summarize the results.' })
2426
.option('summary-log-path', { type: 'string', desc: 'The path to store generation summary information. File will be saved in md format.' });
2527

2628
interface ILogger {
@@ -33,6 +35,7 @@ executeSynchronous(async () => {
3335
let basePaths;
3436
let localPath = args['local-path'];
3537
let summaryPath = args['summary-log-path'];
38+
const combineBatchMode = args['combine-batch-mode'] ?? false;
3639

3740
// localPath refers to the specs repo (azure-rest-api-specs)
3841
if (!localPath) {
@@ -53,8 +56,12 @@ executeSynchronous(async () => {
5356
// resolve absolute path
5457
summaryPath = await resolveAbsolutePath(summaryPath);
5558

56-
if (args['batch-count'] !== undefined && args['batch-index'] !== undefined) {
57-
basePaths = chunker(basePaths, args['batch-count'])[args['batch-index']];
59+
const batchIndex = args['batch-index'];
60+
const batchCount = args['batch-count'];
61+
if (batchCount !== undefined && batchIndex !== undefined) {
62+
basePaths = chunker(basePaths, batchCount)[batchIndex];
63+
64+
console.log(`Generating following base paths for batch ${batchIndex}: ${JSON.stringify(basePaths, null, 2)}`);
5865
}
5966

6067
const schemaConfigs: SchemaConfiguration[] = [];
@@ -81,7 +88,9 @@ executeSynchronous(async () => {
8188
});
8289
}
8390

84-
await clearAutoGeneratedSchemaRefs(filteredAutoGenList);
91+
if (!combineBatchMode) {
92+
await clearAutoGeneratedSchemaRefs(filteredAutoGenList);
93+
}
8594

8695
for (const autoGenConfig of filteredAutoGenList) {
8796
const pkg = {
@@ -135,7 +144,12 @@ executeSynchronous(async () => {
135144

136145
}
137146

138-
await saveAutoGeneratedSchemaRefs(flatten(schemaConfigs));
147+
if (combineBatchMode) {
148+
const schemaConfigFile = path.join(schemasBasePath, 'schemaconfig.json');
149+
await writeJsonFile(schemaConfigFile, schemaConfigs);
150+
} else {
151+
await saveAutoGeneratedSchemaRefs(flatten(schemaConfigs));
152+
}
139153

140154
if (args['output-path']) {
141155
const outputPath = await resolveAbsolutePath(args['output-path']);

0 commit comments

Comments
 (0)