Skip to content

Commit

Permalink
Add Docker image publishing to packaging scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
amarthadan committed Oct 27, 2022
1 parent 1af7b4e commit 80a3781
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 62 deletions.
18 changes: 6 additions & 12 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -129,20 +129,14 @@ jobs:
- name: Publish NPM packages to local NPM registry
run: yarn docker:scripts:publish-packages --npm-registry local --npm-tag ${{ github.sha }} --snapshot
- name: Build Docker containers
run: yarn docker:scripts:build-docker-images --dev --npm-registry local --npm-tag ${{ github.sha }} --docker-tag ${{ github.sha }}
run: yarn docker:scripts:docker:build --dev --npm-registry local --npm-tag ${{ github.sha }} --docker-tag ${{ github.sha }}
- name: Stop local NPM registry
run: yarn docker:scripts:npm-registry:stop
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Push airnode-admin to Docker Hub
run: docker push api3/airnode-admin-dev:${{ github.sha }}
- name: Push airnode-client to Docker Hub
run: docker push api3/airnode-client-dev:${{ github.sha }}
- name: Push airnode-deployer to Docker Hub
run: docker push api3/airnode-deployer-dev:${{ github.sha }}
- name: Publish Docker containers
env:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
run: yarn docker:scripts:docker:publish --dev --docker-tag ${{ github.sha }}
unit-tests:
name: Unit tests
runs-on: ubuntu-latest
Expand Down
58 changes: 50 additions & 8 deletions docker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
This is a Docker container that can:

- Start/stop a local NPM registry Docker container
- Build and publish NPM packages to both local and official (TODO) NPM registry
- Build Docker containers from both local and official NPM packages
- Build and publish NPM packages to both local and official NPM registry
- Build and publish Docker containers from both local and official NPM packages

The container uses so called Docker-in-Docker method to build packages and Docker container in the clean Dockerized
environment.
Expand All @@ -27,7 +27,7 @@ There are three CLI commands available:

- [`npm-registry`](#npm-registry)
- [`publish-packages`](#publish-packages)
- [`build-docker-images`](#build-docker-images)
- [`docker`](#docker)

**To run all the pieces together and build Docker images, you can use the two convenience Yarn targets:**

Expand Down Expand Up @@ -92,19 +92,26 @@ Use the `--npm-tag` option to specify the tag for the published packages.
Use the `--snapshot` option to publish a
[snapshot package](https://github.com/changesets/changesets/blob/main/docs/snapshot-releases.md)

When publishing to the official NPM registry you have to provide `NPM_TOKEN` environment variable containing NPM
registry authentication token.

Example:

```bash
docker run --rm -v $(pwd):/airnode -v /var/run/docker.sock:/var/run/docker.sock api3/airnode-packaging:latest publish-packages --npm-registry local --npm-tag local --snapshot
```

You can use a convenience Yarn target to publish snapshot packages to a local NPM registry:
You can use two convenience Yarn targets to publish snapshot packages to a local or official NPM registry (snapshots
only at the moment):

```bash
yarn docker:scripts:publish-packages:local
yarn docker:scripts:publish-packages:snapshot
```

### build-docker-images
### docker

**build**

```
Build Docker images
Expand Down Expand Up @@ -134,13 +141,48 @@ Use the `--dev` option to build the development images, with the `-dev` suffix i
Example:

```bash
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock api3/airnode-packaging:latest build-docker-images --npm-registry local --npm-tag local --docker-tag local
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock api3/airnode-packaging:latest docker build --npm-registry local --npm-tag local --docker-tag local
```

You can use two convenience Yarn targets for building Docker images from the local NPM packages and from the latest
official ones:

```bash
yarn docker:scripts:build-docker-images:local
yarn docker:scripts:build-docker-images:latest
yarn docker:scripts:docker:build:local
yarn docker:scripts:docker:build:latest
```

**publish**

```
Publish Docker images
Options:
--version Show version number [boolean]
--help Show help [boolean]
-g, --docker-tag Docker tag to build the images under [string] [default: "latest"]
-d, --dev Build Docker dev images (with -dev suffix) [boolean] [default: false]
```

You can publish (push) Airnode Docker images.

Use the `--docker-tag` option to specify the Docker tag of the images that should be pushed.

Use the `--dev` option to push the images, with the `-dev` suffix in their name.

You need to provide two environment variables to authenticate against the DockerHub registry:

- `DOCKERHUB_USERNAME` - DockerHub username
- `DOCKERHUB_TOKEN` - DockerHub access token

Example:

```bash
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -e DOCKERHUB_USERNAME -e DOCKERHUB_TOKEN api3/airnode-packaging:latest docker publish
```

You can use a convenience Yarn target for publishing the latest Docker images:

```bash
docker:scripts:docker:publish:latest
```
104 changes: 67 additions & 37 deletions docker/scripts/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import omitBy from 'lodash/omitBy';
import { logger } from '@api3/airnode-utilities';
import { go, GoResult, goSync } from '@api3/promise-utils';
import { stopNpmRegistry, startNpmRegistry } from './npm-registry';
import { buildDockerImages } from './build-docker-images';
import { buildDockerImages, publishDockerImages } from './docker';
import { publishPackages } from './publish-packages';

// Taken from airnode-deployer
Expand Down Expand Up @@ -88,42 +88,72 @@ yargs(process.argv.slice(2))
});
}
)
.command(
'build-docker-images',
'Build Docker images',
{
'npm-registry': {
alias: 'r',
description: 'NPM registry URL to fetch packages from or a keyword `local` to use a local NPM registry',
default: 'https://registry.npmjs.org/',
type: 'string',
},
'npm-tag': {
alias: 't',
description: 'NPM tag/version of the packages that will be fetched',
default: 'latest',
type: 'string',
},
'docker-tag': {
alias: 'g',
description: 'Docker tag to build the images under',
default: 'latest',
type: 'string',
},
dev: {
alias: 'd',
description: 'Build Docker dev images (with -dev suffix)',
default: false,
type: 'boolean',
},
},
(args) => {
logger.log(`Running command '${args._[0]}' with arguments ${longArguments(args)}`);
runCliCommand(() => {
buildDockerImages(args.npmRegistry, args.npmTag, args.dockerTag, args.dev);
});
}
)
.command('docker', 'Manages Docker images', (yargs) => {
yargs
.command(
'build',
'Build Docker images',
{
'npm-registry': {
alias: 'r',
description: 'NPM registry URL to fetch packages from or a keyword `local` to use a local NPM registry',
default: 'https://registry.npmjs.org/',
type: 'string',
},
'npm-tag': {
alias: 't',
description: 'NPM tag/version of the packages that will be fetched',
default: 'latest',
type: 'string',
},
'docker-tag': {
alias: 'g',
description: 'Docker tag to build the images under',
default: 'latest',
type: 'string',
},
dev: {
alias: 'd',
description: 'Build Docker dev images (with -dev suffix)',
default: false,
type: 'boolean',
},
},
(args) => {
logger.log(`Running command '${args._[0]} ${args._[1]}' with arguments ${longArguments(args)}`);
runCliCommand(() => {
buildDockerImages(args.npmRegistry, args.npmTag, args.dockerTag, args.dev);
});
}
)
.command(
'publish',
'Publish Docker images',
{
'docker-tag': {
alias: 'g',
description: 'Docker tag to build the images under',
default: 'latest',
type: 'string',
},
dev: {
alias: 'd',
description: 'Build Docker dev images (with -dev suffix)',
default: false,
type: 'boolean',
},
},
(args) => {
logger.log(`Running command '${args._[0]} ${args._[1]}' with arguments ${longArguments(args)}`);
runCliCommand(() => {
publishDockerImages(args.dockerTag, args.dev);
});
}
)
.help()
.demandCommand(1)
.strict();
})
.help()
.demandCommand(1)
.strict()
Expand Down
20 changes: 20 additions & 0 deletions docker/scripts/build-docker-images.ts → docker/scripts/docker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,23 @@ export const buildDockerImages = (npmRegistry: string, npmTag: string, dockerTag
`docker build --no-cache --build-arg npmRegistryUrl=${npmRegistryUrl} --build-arg npmTag=${npmTag} --tag api3/airnode-client${devSuffix}:${dockerTag} --file /app/airnode-client/Dockerfile /app/airnode-client`
);
};

const loginDockerHub = () => {
const username = process.env.DOCKERHUB_USERNAME;
const password = process.env.DOCKERHUB_TOKEN;

if (!username || !password) {
throw new Error('Missing DockerHub credentials');
}

runCommand(`docker login --password-stdin --username ${username}`, { input: password });
};

export const publishDockerImages = (dockerTag: string, dev: boolean) => {
const devSuffix = dev ? '-dev' : '';

loginDockerHub();
runCommand(`docker push api3/airnode-admin${devSuffix}:${dockerTag}`);
runCommand(`docker push api3/airnode-deployer${devSuffix}:${dockerTag}`);
runCommand(`docker push api3/airnode-client${devSuffix}:${dockerTag}`);
};
12 changes: 7 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,17 @@
"dev:invoke": "(cd packages/airnode-node && yarn run dev:invoke)",
"dev:list": "(cd packages/airnode-operation && yarn run dev:list)",
"dev:stop": "(cd packages/airnode-operation && yarn run dev:stop)",
"docker:build:images:latest": "yarn docker:scripts:build-docker-images:latest",
"docker:build:images:local": "yarn docker:scripts:npm-registry:start && yarn docker:scripts:publish-packages:local && yarn docker:scripts:build-docker-images:local && yarn docker:scripts:npm-registry:stop",
"docker:build:images:latest": "yarn docker:scripts:docker:build:latest",
"docker:build:images:local": "yarn docker:scripts:npm-registry:start && yarn docker:scripts:publish-packages:local && yarn docker:scripts:docker:build:local && yarn docker:scripts:npm-registry:stop",
"docker:build:latest": "yarn docker:build:packaging && yarn docker:build:images:latest",
"docker:build:local": "yarn docker:build:packaging && yarn docker:build:images:local",
"docker:build:packaging": "yarn docker:scripts:build && docker build --tag api3/airnode-packaging:latest --file docker/Dockerfile .",
"docker:scripts:build": "ncc build docker/scripts/cli.ts -o docker/scripts/dist --no-cache --minify --source-map --transpile-only",
"docker:scripts:build-docker-images": "docker run --rm -v /var/run/docker.sock:/var/run/docker.sock api3/airnode-packaging:latest build-docker-images",
"docker:scripts:build-docker-images:latest": "yarn docker:scripts:build-docker-images",
"docker:scripts:build-docker-images:local": "yarn docker:scripts:build-docker-images --npm-registry local --npm-tag local --docker-tag local",
"docker:scripts:docker:build": "docker run --rm -v /var/run/docker.sock:/var/run/docker.sock api3/airnode-packaging:latest docker build",
"docker:scripts:docker:build:latest": "yarn docker:scripts:docker:build",
"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: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

0 comments on commit 80a3781

Please sign in to comment.