Skip to content

Commit

Permalink
🏗 Cut a new nightly branch using CircleCI's scheduled jobs (dry run) (a…
Browse files Browse the repository at this point in the history
  • Loading branch information
danielrozenberg authored and Mahir committed Sep 9, 2021
1 parent 79029ba commit 8d32246
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 0 deletions.
28 changes: 28 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ executors:
docker:
- image: cimg/base:stable
resource_class: small
node-docker-small:
docker:
- image: cimg/node:lts-browsers
resource_class: small
node-docker-medium:
docker:
- image: cimg/node:lts-browsers
Expand Down Expand Up @@ -427,8 +431,17 @@ jobs:
command: node build-system/pr-check/experiment-e2e-tests.js --experiment=experiment<< parameters.exp >>
- store_test_output
- teardown_vm
cut_nightly:
executor:
name: node-docker-small
steps:
- run:
name: '⭐ Cut Nightly Branch ⭐'
command: node --unhandled-rejections=strict build-system/release-workflows/cut-nightly.js

workflows:
version: 2

'CircleCI':
jobs:
- initialize_repository:
Expand Down Expand Up @@ -566,3 +579,18 @@ workflows:
# <<: *push_builds_only
# requires:
# - 'Nomodule Build (Test)'

'Nightly':
triggers:
- schedule:
# 1 a.m. PST / 12 a.m. PDT, Tuesdays through Saturdays.
cron: '0 8 * * 2-6'
filters:
branches:
only:
- main
jobs:
- initialize_repository:
name: 'Initialize Repository'
- cut_nightly:
name: 'Cut Nightly Branch'
104 changes: 104 additions & 0 deletions build-system/release-workflows/cut-nightly.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
'use strict';

/**
* @fileoverview Script that cuts a nightly branch.
*/

const {cyan, green, red, yellow} = require('../common/colors');
const {log} = require('../common/logging');
const {Octokit} = require('@octokit/rest');

// TODO(danielrozenberg): remove this once the Google-backed job is turned off.
const DRY_RUN = true;

const params = {owner: 'ampproject', repo: 'amphtml'};

const colorizeState = (state) =>
state == 'error' || state == 'failure'
? red(state)
: state == 'pending'
? yellow(state)
: state == 'success'
? green(state)
: state;

/**
* Perform nightly branch cut.
*
* @return {Promise<void>}
*/
async function cutNightlyBranch() {
const octokit = new Octokit({auth: process.env.GITHUB_TOKEN});
octokit.hook.error('request', async (error, options) => {
log(
red('Error occurred while calling GitHub API with'),
cyan(options.method),
cyan(options.url)
);
throw new Error(error.message);
});

const commits = await octokit.rest.repos.listCommits({
...params,
ref: 'main',
'per_page': 100,
});
log(
'Iterating the latest',
cyan(commits.data.length),
'commits on',
cyan('main')
);

for (const {sha} of commits.data) {
const commitStatus = await octokit.rest.repos.getCombinedStatusForRef({
...params,
ref: sha,
});
const {state} = commitStatus.data;

log('Status of commit', cyan(sha), 'is', colorizeState(state));

if (state === 'success') {
if (DRY_RUN) {
log(yellow('NOTE:'), 'this job is running in DRY_RUN mode.');
break;
}

const response = await octokit.rest.git.updateRef({
...params,
ref: 'heads/nightly',
sha,
});

// Casting to Number because the return type in Octokit is incorrectly
// annotated to only ever return 200.
switch (Number(response.status)) {
case 201:
log('Cut a new', cyan('nightly'), 'with', cyan(sha));
break;
case 200:
log(
'The',
cyan('nightly'),
'branch is already at the latest',
green('green'),
'sha',
cyan(sha)
);
break;
default:
log(
red('An error occurred while attempting to fast-forward the'),
cyan('nightly'),
red('branch to sha'),
cyan(sha)
);
}

break;
}
}
}

cutNightlyBranch();

0 comments on commit 8d32246

Please sign in to comment.