diff --git a/.github/workflows/self-test-multistage-docker-build.yml b/.github/workflows/self-test-multistage-docker-build.yml index 7fef14d..9f28d04 100644 --- a/.github/workflows/self-test-multistage-docker-build.yml +++ b/.github/workflows/self-test-multistage-docker-build.yml @@ -13,6 +13,37 @@ permissions: packages: write jobs: + test-build-auto-repo: + name: Automatic repository naming + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Auth to GH registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - uses: ./ + id: build + with: + dockerfile: examples/Dockerfile + registry: ghcr.io + stages: env, configured + server-stage: server + + - name: Print outputs + run: | + echo "Server: ${{ steps.build.outputs.server-tag }}" + echo "Testenv: ${{ steps.build.outputs.testenv-tag }}" + echo "Commit: ${{ steps.build.outputs.commit }}" + + - name: Run image + run: docker run --rm ${{ steps.build.outputs.server-tag }} + + test-build-parallel-setting: name: Parallel via setting runs-on: ubuntu-latest diff --git a/README.md b/README.md index a1e057f..eac70e5 100644 --- a/README.md +++ b/README.md @@ -16,16 +16,27 @@ While the action allows many stages to be pushed to the registry for future re-u | Input | Required | Default | Description | |---|---|---|---| -| `repository` | **yes** | | Repository name for pushed images | -| `stages` | **yes** | | Comma-separarted list of build stages. Each of these will be an explicit cache target for subsequent builds | | `server-stage` | **yes** | | Name of stage for server | -| `tag-latest-on-default` | no | `true` | Automatically create a `latest` tag when run on the default branch | -| `testenv-stage` | no | | Name of stage for test environment | +| `stages` | **yes** | | Comma-separarted list of build stages. Each of these will be an explicit cache target for subsequent builds | +| `build-args` | no | | Comma-separated list of `--build-arg` flags. | | `context` | no | `.` | Build context | | `dockerfile` | no | `Dockerfile` | Path to the Dockerfile | -| `quiet` | no | `true` | Should docker commands be passed `--quiet` | | `parallel` | no | `false` | Should stages be built in parallel (via BuildX) | -| `build-args` | no | | Comma-separated list of `--build-arg` flags. | +| `quiet` | no | `true` | Should docker commands be passed `--quiet` | +| `repository` | no[^1] | | Repository name for pushed images | +| `registry` | no[^1] | | Docker registry for automatically-named images | +| `tag-latest-on-default` | no | `true` | Automatically create a `latest` tag when run on the default branch | +| `testenv-stage` | no | | Name of stage for test environment | + +### `registry` and `repository` +In versions `v1.7.x` and earlier, the `repository` input is used to control where the built images go. +It should include the registry in the value (e.g. `ghcr.io`, `gcr.io`, etc.). + +As of `v1.8`, you can leave `repository` blank and instead provide only the `registry`. +If you do so, the Github repository name will be used to produce the outputs. + +You **must** set either value, but not both. +This limitation may be removed in a future version. ### Parallel builds The new `parallel` option, added in `v1.7`, defaults to off. @@ -124,3 +135,5 @@ tl:dr: If it comes from one of the `outputs` of this action, go ahead and use it ## Known issues/Future features - Make a straightforward mechanism to do cleanup + +[^1]: You must provide either of these values, but do not provide both. diff --git a/action.yml b/action.yml index 902d3bd..deb6ebf 100644 --- a/action.yml +++ b/action.yml @@ -21,8 +21,11 @@ inputs: description: Build in parallel required: false default: false + registry: + required: false + description: Registry to pull from and push to. Can be provided through `repository` repository: - required: true + required: false description: Repository that all of the images and tags will pull from and push to stages: required: true diff --git a/dist/index.js b/dist/index.js index 4522087..a80f3c9 100644 --- a/dist/index.js +++ b/dist/index.js @@ -10887,8 +10887,27 @@ exports.getAllStages = getAllStages; * Takes the build stage and returns an untagged image name for it */ function getUntaggedImageForStage(stage) { - const repo = core.getInput('repository'); - return `${repo}/${stage}`; + const reg = core.getInput('registry'); + let repo = core.getInput('repository'); + if (reg === '' && repo === '') { + // Technically, this should be permissible. In practice, the default + // `docker push` going to Docker Hub when a registry isn't specified will + // break - so it's forbidden. + throw new Error('Registry and repository must not both be blank'); + } + if (reg !== '' && repo !== '') { + // This is a temporary limitation - I'm not sure exactly what behavior is + // most desirable here. The main use-case of `registry` is to leave out + // `repository` so for now we're optimizing for that. + throw new Error('Use registry OR repository, but not both'); + } + if (repo === '') { + repo = (github.context.repo.owner + '/' + github.context.repo.repo).toLowerCase(); + return `${reg}/${repo}/${stage}`; + } + else { + return `${repo}/${stage}`; + } } function getTaggedImageForStage(stage, tag) { const image = getUntaggedImageForStage(stage); diff --git a/src/helpers.ts b/src/helpers.ts index 746f51e..aae088e 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -83,8 +83,29 @@ export function getAllStages(): string[] { * Takes the build stage and returns an untagged image name for it */ function getUntaggedImageForStage(stage: string): string { - const repo = core.getInput('repository') - return `${repo}/${stage}` + const reg = core.getInput('registry') + let repo = core.getInput('repository') + + if (reg === '' && repo === '') { + // Technically, this should be permissible. In practice, the default + // `docker push` going to Docker Hub when a registry isn't specified will + // break - so it's forbidden. + throw new Error('Registry and repository must not both be blank') + } + + if (reg !== '' && repo !== '') { + // This is a temporary limitation - I'm not sure exactly what behavior is + // most desirable here. The main use-case of `registry` is to leave out + // `repository` so for now we're optimizing for that. + throw new Error('Use registry OR repository, but not both') + } + + if (repo === '') { + repo = (github.context.repo.owner + '/' + github.context.repo.repo).toLowerCase() + return `${reg}/${repo}/${stage}` + } else { + return `${repo}/${stage}` + } } export function getTaggedImageForStage(stage: string, tag: string): string {