-
Notifications
You must be signed in to change notification settings - Fork 253
JDBetteridge/Composite actions #2868
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
7e414c9
0d6bda8
e079057
b291607
8390d9c
b49219f
1dc1857
f8abdae
e722b59
b4035ec
55cae25
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| name: Docker build action | ||
| description: Composite action for building Devito Docker containers | ||
| author: "Devito" | ||
|
|
||
| inputs: | ||
| # The only supported GHA input type is string | ||
| file: | ||
| description: "Dockerfile containing build instructions" | ||
| required: true | ||
| default: Dockerfile | ||
| tag: | ||
| description: "Tag to add to the built image" | ||
| required: true | ||
| base: | ||
| description: "Base docker image to build on top of" | ||
| default: "" | ||
| args: | ||
| description: "Arguments to pass to `docker build`" | ||
| required: true | ||
| default: "" | ||
|
|
||
| outputs: | ||
| unique: | ||
| description: "Unique identifier for the CI run" | ||
| value: ${{ steps.uniquetag.outputs.unique }} | ||
|
|
||
| runs: | ||
| using: "composite" | ||
| steps: | ||
| - id: uniquetag | ||
| name: "Generate unique CI tag" | ||
| shell: bash | ||
| run: | | ||
| UNIQUE=$(echo "${GITHUB_RUN_ID}_${GITHUB_RUN_ATTEMPT}" | cksum | cut -f 1 -d " ") | ||
| echo "Unique ID: ${UNIQUE}" | ||
| echo "unique=${UNIQUE}" >> "$GITHUB_OUTPUT" | ||
| - id: dockerbuild | ||
| name: "Build docker container" | ||
| shell: bash | ||
| env: | ||
| BASE: ${{ inputs.base }} | ||
| run: | | ||
| docker build \ | ||
| --pull \ | ||
| --file ${{ inputs.file }} \ | ||
| --tag ${{ inputs.tag }}_${{ steps.uniquetag.outputs.unique }} \ | ||
| ${BASE:+--build-arg base=$BASE} \ | ||
| ${{ inputs.args }} \ | ||
| . | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| name: Docker cleanup action | ||
| description: Composite action for removing Docker images | ||
| author: "Devito" | ||
|
|
||
| inputs: | ||
| # The only supported GHA input type is string | ||
| uid: | ||
| description: "Unique identifier output from docker-build action" | ||
| required: true | ||
| tag: | ||
|
Comment on lines
+7
to
+10
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I pass both |
||
| description: "Tag of the built image to use" | ||
| required: true | ||
|
|
||
| runs: | ||
| using: "composite" | ||
| steps: | ||
| - id: dockerclean | ||
| name: "Cleanup docker image" | ||
| shell: bash | ||
| run: | | ||
| docker image rm -f "${{ inputs.tag }}_${{ inputs.uid }}" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| name: Docker run action | ||
| description: Composite action for running commands in Docker containers | ||
| author: "Devito" | ||
|
|
||
| inputs: | ||
| # The only supported GHA input type is string | ||
| uid: | ||
| description: "Unique identifier output from docker-build action" | ||
| required: true | ||
| tag: | ||
| description: "Tag of the built image to use" | ||
| required: true | ||
| name: | ||
| description: "Name substring for docker to use when running the command" | ||
| default: "" | ||
| args: | ||
| description: "Arguments to pass to `docker run`, `--init -t --rm` are always added" | ||
| required: true | ||
| default: "" | ||
| env: | ||
| description: "Environment variables to set inside the docker container, one environment variable per line" | ||
| required: true | ||
| default: "" | ||
| command: | ||
| description: "Command to execute inside of the docker container" | ||
| required: true | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A limitation of this approach is that only one command can be run in a container at once, making the workflows a little verbose in some places. |
||
|
|
||
| runs: | ||
| using: "composite" | ||
| steps: | ||
| - id: processenv | ||
| name: Process environment variable list | ||
| shell: bash | ||
| env: | ||
| ENV_INPUT: ${{ inputs.env }} | ||
| run: | | ||
| ENV_STRING="" | ||
| # Read line by line with here string, safely handling spaces within the values | ||
| while IFS= read -r LINE; do | ||
| if [[ -n "$LINE" ]]; then | ||
| ENV_STRING="$ENV_STRING --env $LINE" | ||
| fi | ||
| done <<< "$ENV_INPUT" | ||
| # Remove the leading space from the first concatenation | ||
| ENV_STRING="${ENV_STRING# }" | ||
| echo "docker_environment_args=$ENV_STRING" >> "$GITHUB_OUTPUT" | ||
|
|
||
| - id: dockerrun | ||
| name: "Run command ${{ inputs.command }} in ${{ inputs.tag }} docker container" | ||
| shell: bash | ||
| env: | ||
| NAME: ${{ input.name }} | ||
| run: | | ||
| docker run \ | ||
| --init -t --rm \ | ||
| ${{ inputs.args }} \ | ||
| --name "ci-${NAME:-${{ inputs.tag }}}-${{ inputs.uid }}" \ | ||
| --env-file=docker/coverage.env \ | ||
JDBetteridge marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ${{ steps.processenv.outputs.docker_environment_args }} \ | ||
| "${{ inputs.tag }}_${{ inputs.uid }}" \ | ||
| ${{ inputs.command }} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| # Devito Actions | ||
|
|
||
| The Devito actions can either be used from the Github interface: | ||
| ```yaml | ||
| uses: devitocodes/devito/.github/actions/docker-build@main | ||
| ``` | ||
|
|
||
| Or internally from within the repository: | ||
| ```yaml | ||
| uses: ./.github/actions/docker-run | ||
| ``` | ||
|
|
||
| ## `docker-build` | ||
|
|
||
| Inputs: | ||
|
|
||
| - `file`: Dockerfile containing build instructions (default: `Dockerfile`) | ||
| - `tag`: Tag to add to the built image | ||
| - `base`: Base docker image to build on top of | ||
| - `args`: Arguments to pass to `docker build` | ||
|
|
||
| Outputs: | ||
|
|
||
| - `unique`: Unique identifier for the CI run (ie: `${{ steps.build.outputs.unique }}`) | ||
|
|
||
| Example: | ||
|
|
||
| ```yaml | ||
| jobs: | ||
| test: | ||
| steps: | ||
| - id: build | ||
| name: Build docker image for Devito | ||
| uses: ./.github/actions/docker-build | ||
| with: | ||
| file: docker/Dockerfile.devito | ||
| tag: tag-related-to-test-config | ||
| base: base-image-to-build-from | ||
| args: "--more-docker-build-args" | ||
| ``` | ||
|
|
||
| ## `docker-run` | ||
|
|
||
| Inputs: | ||
|
|
||
| - `uid`: Unique identifier output from docker-build action | ||
| - `tag`: Tag of the built image to use | ||
| - `name`: Name substring for docker to use when running the command (optional) | ||
| - `args`: Arguments to pass to `docker run`, `--init -t --rm` are always added | ||
| - `env`: Environment variables to set inside the docker container, one environment variable per line | ||
| -command: Command to execute inside of the docker container | ||
|
|
||
| ### Notes | ||
|
|
||
| - The UID must be unique, easily obtained from build action | ||
| - The tag must match built image, easily obtained from build action | ||
| - If you provide a custom name `foo` the container name will be `ci-foo-UUUUUUUUUU` where UUUUUUUUUU is the UID | ||
| - The default args `--init -t --rm` are _always_ added | ||
| - Environment variables must be passed a single environment variable per line, best achieved with the (`|`) syntax in yaml | ||
| - Only a single command is executed, not a list of commands. Using `;` or `&&` will result in subsequent commands being executed outside of the docker environment | ||
|
|
||
| Example: | ||
|
|
||
| ```yaml | ||
| jobs: | ||
| test: | ||
| steps: | ||
| - name: Run a command in a previously built Docker container | ||
| uses: ./.github/actions/docker-run | ||
| with: | ||
| uid: ${{ steps.build.outputs.unique }} | ||
| tag: tag-related-to-test-config | ||
| name: completely-optional-name | ||
| args: "--more-docker-run-args" | ||
| env: | | ||
| FOO=value1 | ||
| BAR=value2 | ||
| command: | | ||
| mpiexec -n 4 \ | ||
| python \ | ||
| my_complicated_script.py --arg1 -v | ||
| ``` | ||
|
|
||
| ## `docker-clean` | ||
|
|
||
| Inputs: | ||
|
|
||
| - `uid`: Unique identifier output from docker-build action | ||
| - `tag`: Tag of the built image to use | ||
|
|
||
| ### Notes | ||
|
|
||
| - UID must be unique, easily obtained from build action | ||
| - Tag must match built image, easily obtained from build action | ||
| - Use `if: always()` to always clean up the image, even if the workflow fails | ||
|
|
||
| Example: | ||
|
|
||
| ```yaml | ||
| jobs: | ||
| test: | ||
| steps: | ||
| - name: Cleanup Docker image | ||
| if: always() | ||
| uses: ./.github/actions/docker-clean | ||
| with: | ||
| uid: ${{ steps.build.outputs.unique }} | ||
| tag: tag-related-to-test-config | ||
| ``` |
Uh oh!
There was an error while loading. Please reload this page.