Skip to content

Commit

Permalink
Merge pull request #1508 from api3dao/packaging-prevent-merge
Browse files Browse the repository at this point in the history
Add CI job to enable/disable GH PR merging
  • Loading branch information
amarthadan authored Oct 27, 2022
2 parents 4a4bbea + 632f93d commit 66636e8
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 19 deletions.
10 changes: 9 additions & 1 deletion .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,18 @@ jobs:
# https://github.com/renovatebot/renovate/discussions/13704#discussioncomment-2013280
if: github.actor != 'renovate[bot]'
run: yarn changeset:check
enable-merge:
name: Enable PR merge
runs-on: ubuntu-latest
steps:
- name: Check the ENABLE_MERGE secret
env:
ENABLE_MERGE: ${{ secrets.ENABLE_MERGE }}
run: test $ENABLE_MERGE = true && exit 0 || exit 1
build-complete:
name: All tests passed
runs-on: ubuntu-latest
needs: [documentation, docker-build, unit-tests, e2e-tests, e2e-tests-examples, require-changeset]
needs: [documentation, docker-build, unit-tests, e2e-tests, e2e-tests-examples, require-changeset, enable-merge]
steps:
- run: exit 0
- name: Slack Notification
Expand Down
38 changes: 32 additions & 6 deletions docker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

This is a Docker container that can:

- Enable/disable GitHub pull-request merging
- Start/stop a local NPM registry Docker container
- Build and publish NPM packages to both local and official NPM registry
- Build and publish Docker containers from both local and official NPM packages
Expand All @@ -23,8 +24,9 @@ allow conditional build steps. You can read more about how to enable it in its

## Usage

There are three CLI commands available:
There are four CLI commands available:

- [`github`](#github)
- [`npm-registry`](#npm-registry)
- [`publish-packages`](#publish-packages)
- [`docker`](#docker)
Expand All @@ -36,18 +38,42 @@ yarn docker:build:local
yarn docker:build:latest
```

### github

```
Manages GitHub PR merging
Commands:
index.js github enable-merge Enables PR merging
index.js github disable-merge Disables PR merging
```

You can enable and disable GitHub pull-request merging. Disabling merging is useful during the release process so the
`master` branch won't move untill the packages are released.

You need to provide `GITHUB_TOKEN` environment variable containing GitHub atuhentication token.

Example:

```bash
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -e GITHUB_TOKEN api3/airnode-packaging:latest github enable-merge
```

You can use two convenience Yarn targets for enabling and disabling PR merging:

```bash
yarn docker:scripts:github:enable-merge
yarn docker:scripts:github:disable-merge
```

### npm-registry

```
Manages the local NPM registry
Commands:
index.js npm-registry start Start the local NPM registry
index.js npm-registry stop Stop the local NPM registry
Options:
--version Show version number [boolean]
--help Show help [boolean]
index.js npm-registry stop Stop the local NPM registry [boolean]
```

You can start and stop a local NPM registry. Can be useful for manual package testing but it's mostly a step needed for
Expand Down
31 changes: 19 additions & 12 deletions docker/scripts/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { go, GoResult, goSync } from '@api3/promise-utils';
import { stopNpmRegistry, startNpmRegistry } from './npm-registry';
import { buildDockerImages, publishDockerImages } from './docker';
import { publishPackages } from './publish-packages';
import { disableMerge, enableMerge } from './github';

// Taken from airnode-deployer
const longArguments = (args: Record<string, any>) => {
Expand Down Expand Up @@ -43,9 +44,7 @@ yargs(process.argv.slice(2))
})
.command('stop', 'Stop the local NPM registry', {}, (args) => {
logger.log(`Running command '${args._[0]} ${args._[1]}' with arguments ${longArguments(args)}`);
runCliCommand(() => {
stopNpmRegistry();
});
runCliCommand(() => stopNpmRegistry());
})
.help()
.demandCommand(1)
Expand Down Expand Up @@ -83,9 +82,7 @@ yargs(process.argv.slice(2))
throw new Error('Only snapshot packages are supported at the moment');
}

runCliCommand(() => {
publishPackages(args.npmRegistry, args.npmTag, args.snapshot);
});
runCliCommand(() => publishPackages(args.npmRegistry, args.npmTag, args.snapshot));
}
)
.command('docker', 'Manages Docker images', (yargs) => {
Expand Down Expand Up @@ -121,9 +118,7 @@ yargs(process.argv.slice(2))
},
(args) => {
logger.log(`Running command '${args._[0]} ${args._[1]}' with arguments ${longArguments(args)}`);
runCliCommand(() => {
buildDockerImages(args.npmRegistry, args.npmTag, args.dockerTag, args.dev);
});
runCliCommand(() => buildDockerImages(args.npmRegistry, args.npmTag, args.dockerTag, args.dev));
}
)
.command(
Expand All @@ -145,15 +140,27 @@ yargs(process.argv.slice(2))
},
(args) => {
logger.log(`Running command '${args._[0]} ${args._[1]}' with arguments ${longArguments(args)}`);
runCliCommand(() => {
publishDockerImages(args.dockerTag, args.dev);
});
runCliCommand(() => publishDockerImages(args.dockerTag, args.dev));
}
)
.help()
.demandCommand(1)
.strict();
})
.command('github', 'Manages GitHub PR merging', (yargs) => {
yargs
.command('enable-merge', 'Enables PR merging', {}, (args) => {
logger.log(`Running command '${args._[0]} ${args._[1]}' with arguments ${longArguments(args)}`);
runCliCommand(() => enableMerge());
})
.command('disable-merge', 'Disables PR merging', {}, (args) => {
logger.log(`Running command '${args._[0]} ${args._[1]}' with arguments ${longArguments(args)}`);
runCliCommand(() => disableMerge());
})
.help()
.demandCommand(1)
.strict();
})
.help()
.demandCommand(1)
.strict()
Expand Down
66 changes: 66 additions & 0 deletions docker/scripts/github.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import sodium from 'libsodium-wrappers';
import { Octokit } from '@octokit/core';
import { go } from '@api3/promise-utils';
import { logger } from '@api3/airnode-utilities';

const OWNER = 'api3dao';
const REPOSITORY = 'airnode';

const toggleMerge = async (flag: boolean) => {
logger.log(`Setting 'ENABLE_MERGE' flag to '${flag}' for repository '${OWNER}/${REPOSITORY}'`);

const githubToken = process.env.GITHUB_TOKEN;
if (!githubToken) {
throw new Error('Missing GitHub token');
}

const octokit = new Octokit({
auth: githubToken,
});

const goPubKey = await go(() =>
octokit.request(`GET /repos/${OWNER}/${REPOSITORY}/actions/secrets/public-key`, {
owner: OWNER,
repo: REPOSITORY,
})
);
if (!goPubKey.success) {
throw new Error(`Can't obtain GitHub repository public key: ${goPubKey.error}`);
}

const repositoryPublicKey = goPubKey.data.data.key as string;
const repositoryPublicKeyId = goPubKey.data.data.key_id as string;

logger.log(`Repository public key: ${repositoryPublicKey} with ID ${repositoryPublicKeyId}`);

const goSodium = await go(() => sodium.ready);
if (!goSodium.success) {
throw new Error(`Can't load the sodium encryption library: ${goSodium.error}`);
}

// Convert Secret & Base64 key to Uint8Array.
const binKey = sodium.from_base64(repositoryPublicKey, sodium.base64_variants.ORIGINAL);
const binSecret = sodium.from_string(`${flag}`);

// Encrypt the secret using LibSodium
const encSecret = sodium.crypto_box_seal(binSecret, binKey);

// Convert encrypted Uint8Array to Base64
const base64Secret = sodium.to_base64(encSecret, sodium.base64_variants.ORIGINAL);

const goSecret = await go(() =>
octokit.request(`PUT /repos/${OWNER}/${REPOSITORY}/actions/secrets/ENABLE_MERGE`, {
owner: OWNER,
repo: REPOSITORY,
secret_name: 'ENABLE_MERGE',
encrypted_value: base64Secret,
key_id: repositoryPublicKeyId,
})
);
if (!goSecret.success) {
throw new Error(`Can't update GitHub repository secret: ${goSecret.error}`);
}
};

export const enableMerge = () => toggleMerge(true);
export const disableMerge = () => toggleMerge(false);
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@
"docker:scripts:docker:build:local": "yarn docker:scripts:docker:build --npm-registry local --npm-tag local --docker-tag local",
"docker:scripts:docker:publish": "docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -e DOCKERHUB_USERNAME -e DOCKERHUB_TOKEN api3/airnode-packaging:latest docker publish",
"docker:scripts:docker:publish:latest": "yarn docker:scripts:docker:publish",
"docker:scripts:github": "docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -e GITHUB_TOKEN api3/airnode-packaging:latest github",
"docker:scripts:github:enable-merge": "yarn docker:scripts:github enable-merge",
"docker:scripts:github:disable-merge": "yarn docker:scripts:github disable-merge",
"docker:scripts:npm-registry": "docker run --rm -v /var/run/docker.sock:/var/run/docker.sock api3/airnode-packaging:latest npm-registry",
"docker:scripts:npm-registry:start": "yarn docker:scripts:npm-registry start",
"docker:scripts:npm-registry:stop": "yarn docker:scripts:npm-registry stop",
Expand Down Expand Up @@ -102,6 +105,8 @@
"@api3/promise-utils": "^0.3.0",
"@changesets/changelog-github": "^0.4.7",
"@changesets/cli": "^2.25.0",
"@octokit/core": "^4.1.0",
"@types/libsodium-wrappers": "^0.7.10",
"@types/node": "^17.0.18",
"@typescript-eslint/eslint-plugin": "^5.40.1",
"@typescript-eslint/parser": "^5.40.1",
Expand All @@ -115,6 +120,7 @@
"fast-glob": "^3.2.12",
"husky": "^8.0.1",
"lerna": "^6.0.1",
"libsodium-wrappers": "^0.7.10",
"prettier": "^2.7.1",
"prettier-plugin-solidity": "^1.0.0-dev.23",
"rimraf": "^3.0.2",
Expand Down
42 changes: 42 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2398,6 +2398,19 @@
before-after-hook "^2.2.0"
universal-user-agent "^6.0.0"

"@octokit/core@^4.1.0":
version "4.1.0"
resolved "https://registry.yarnpkg.com/@octokit/core/-/core-4.1.0.tgz#b6b03a478f1716de92b3f4ec4fd64d05ba5a9251"
integrity sha512-Czz/59VefU+kKDy+ZfDwtOIYIkFjExOKf+HA92aiTZJ6EfWpFzYQWw0l54ji8bVmyhc+mGaLUbSUmXazG7z5OQ==
dependencies:
"@octokit/auth-token" "^3.0.0"
"@octokit/graphql" "^5.0.0"
"@octokit/request" "^6.0.0"
"@octokit/request-error" "^3.0.0"
"@octokit/types" "^8.0.0"
before-after-hook "^2.2.0"
universal-user-agent "^6.0.0"

"@octokit/endpoint@^7.0.0":
version "7.0.2"
resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-7.0.2.tgz#11ee868406ba7bb1642e61bbe676d641f79f02be"
Expand All @@ -2421,6 +2434,11 @@
resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-13.13.0.tgz#c9bd7fafd41984176a806938e0a56b7c39425014"
integrity sha512-EQ7/LFp2nb1bU5vhLvfEsImi7RvGXp081ytaMRQXDyVcpLpmOCUMafYfHL72BA7wCOnEmJR0LznBS6sCAIlm9Q==

"@octokit/openapi-types@^14.0.0":
version "14.0.0"
resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-14.0.0.tgz#949c5019028c93f189abbc2fb42f333290f7134a"
integrity sha512-HNWisMYlR8VCnNurDU6os2ikx0s0VyEjDYHNS/h4cgb8DeOxQ0n72HyinUtdDVxJhFy3FWLGl0DJhfEWk3P5Iw==

"@octokit/plugin-enterprise-rest@^6.0.1":
version "6.0.1"
resolved "https://registry.yarnpkg.com/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz#e07896739618dab8da7d4077c658003775f95437"
Expand Down Expand Up @@ -2484,6 +2502,13 @@
dependencies:
"@octokit/openapi-types" "^13.11.0"

"@octokit/types@^8.0.0":
version "8.0.0"
resolved "https://registry.yarnpkg.com/@octokit/types/-/types-8.0.0.tgz#93f0b865786c4153f0f6924da067fe0bb7426a9f"
integrity sha512-65/TPpOJP1i3K4lBJMnWqPUJ6zuOtzhtagDvydAWbEXpbFYA0oMKKyLb95NFZZP0lSh/4b6K+DQlzvYQJQQePg==
dependencies:
"@octokit/openapi-types" "^14.0.0"

"@opencensus/[email protected]":
version "0.0.9"
resolved "https://registry.yarnpkg.com/@opencensus/core/-/core-0.0.9.tgz#b16f775435ee309433e4126af194d37313fc93b3"
Expand Down Expand Up @@ -3050,6 +3075,11 @@
"@types/level-errors" "*"
"@types/node" "*"

"@types/libsodium-wrappers@^0.7.10":
version "0.7.10"
resolved "https://registry.yarnpkg.com/@types/libsodium-wrappers/-/libsodium-wrappers-0.7.10.tgz#a6ebde70d3b4af960fd802af8d0e3c7cfe281eb2"
integrity sha512-BqI9B92u+cM3ccp8mpHf+HzJ8fBlRwdmyd6+fz3p99m3V6ifT5O3zmOMi612PGkpeFeG/G6loxUnzlDNhfjPSA==

"@types/lodash@^4.14.186":
version "4.14.186"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.186.tgz#862e5514dd7bd66ada6c70ee5fce844b06c8ee97"
Expand Down Expand Up @@ -11270,6 +11300,18 @@ libnpmpublish@^6.0.4:
semver "^7.3.7"
ssri "^9.0.0"

libsodium-wrappers@^0.7.10:
version "0.7.10"
resolved "https://registry.yarnpkg.com/libsodium-wrappers/-/libsodium-wrappers-0.7.10.tgz#13ced44cacb0fc44d6ac9ce67d725956089ce733"
integrity sha512-pO3F1Q9NPLB/MWIhehim42b/Fwb30JNScCNh8TcQ/kIc+qGLQch8ag8wb0keK3EP5kbGakk1H8Wwo7v+36rNQg==
dependencies:
libsodium "^0.7.0"

libsodium@^0.7.0:
version "0.7.10"
resolved "https://registry.yarnpkg.com/libsodium/-/libsodium-0.7.10.tgz#c2429a7e4c0836f879d701fec2c8a208af024159"
integrity sha512-eY+z7hDrDKxkAK+QKZVNv92A5KYkxfvIshtBJkmg5TSiCnYqZP3i9OO9whE79Pwgm4jGaoHgkM4ao/b9Cyu4zQ==

lines-and-columns@^1.1.6:
version "1.2.4"
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
Expand Down

0 comments on commit 66636e8

Please sign in to comment.