UNPKG

@atomist/sdm

Version:

Atomist Software Delivery Machine SDK

174 lines (152 loc) 5.29 kB
/* * Copyright © 2020 Atomist, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { GitProject } from "@atomist/automation-client/lib/project/git/GitProject"; import { Goal, GoalDefinition } from "../../../api/goal/Goal"; import { DefaultGoalNameGenerator } from "../../../api/goal/GoalNameGenerator"; import { FulfillableGoalDetails, FulfillableGoalWithRegistrations, getGoalDefinitionFrom, ImplementationRegistration, mergeOptions, } from "../../../api/goal/GoalWithFulfillment"; import { IndependentOfEnvironment } from "../../../api/goal/support/environment"; import { DockerProgressReporter } from "./DockerProgressReporter"; import { DefaultDockerImageNameCreator, DockerImageNameCreator, executeDockerBuild } from "./executeDockerBuild"; export interface DockerRegistry { /** * Push Url for this registry */ registry: string; /** * Should this registry be displayed with the goal status after a push? Default true. */ display?: boolean; /** * Display Url - ie the url humans can go to * assumes <url>/<image> */ displayUrl?: string; /** * If specified, this will replace the label version details (eg <image><:version>) * For example, for Dockerhub the correct value would be `/tags`, with a displayUrl set * to https://hub.docker.com/r/<user/org>; will result in: * https://hub.docker.com/r/<user/org>/<image>/tags as the link URL * */ displayBrowsePath?: string; /** * How should urls to this registry be labeled? * ie DockerHub, ECR, etc (friendly name instead of big tag string) * if not supplied, we'll display the tag */ label?: string; user?: string; password?: string; } /** * Options to configure the Docker image build */ export interface DockerOptions extends Partial<ImplementationRegistration> { /** * Provide the image tag for the docker image to build */ dockerImageNameCreator?: DockerImageNameCreator; /** * True if the docker image should be pushed to the registry */ push?: boolean; /** * True if pushes should happen concurrently */ concurrentPush?: boolean; /** * Optional registries to push the docker image too. * Needs to set when push === true */ registry?: DockerRegistry | DockerRegistry[]; /** * Optional Docker config in json as alternative to running * 'docker login' with provided registry, user and password. */ config?: string; /** * Find the Dockerfile within the project * @param p the project */ dockerfileFinder?: (p: GitProject) => Promise<string>; /** * Optionally specify what docker image builder to use. * Defaults to "docker" */ builder?: "docker" | "kaniko"; /** * Optional arguments passed to the docker image builder */ builderArgs?: string[]; /** * Path relative to base of project to build. If not provided, * ".", i.e., the project base directory, is used. */ builderPath?: string; } const DefaultDockerOptions: DockerOptions = { dockerImageNameCreator: DefaultDockerImageNameCreator, dockerfileFinder: async () => "Dockerfile", builder: "docker", builderArgs: [], builderPath: ".", }; /** * Goal that performs docker build and push depending on the provided options */ export class DockerBuild extends FulfillableGoalWithRegistrations<DockerOptions> { constructor( goalDetailsOrUniqueName: FulfillableGoalDetails | string = DefaultGoalNameGenerator.generateName( "docker-build", ), ...dependsOn: Goal[] ) { super( getGoalDefinitionFrom( goalDetailsOrUniqueName, DefaultGoalNameGenerator.generateName("docker-build"), DockerBuildDefinition, ), ...dependsOn, ); } public with(registration: DockerOptions): this { const optsToUse = mergeOptions<DockerOptions>(DefaultDockerOptions, registration); this.addFulfillment({ goalExecutor: executeDockerBuild(optsToUse), name: DefaultGoalNameGenerator.generateName("docker-builder"), progressReporter: DockerProgressReporter, ...(registration as ImplementationRegistration), }); return this; } } const DockerBuildDefinition: GoalDefinition = { uniqueName: "docker-build", displayName: "docker build", environment: IndependentOfEnvironment, workingDescription: "Running docker build", completedDescription: "Docker build successful", failedDescription: "Docker build failed", isolated: true, retryFeasible: true, };