In this hands-on lab you will create a docker container action that uses input and output parameters. Furthermore, you will create a CI build that tests the action every time y change is made to one of the files.
The lab consists of the following parts:
- Use the template to create a new repo
- Create the dockerfile for the action
- Create the action.yml file
- Create the entrypoint.sh file
- Create a workflow to test the action
In this repository, under Code, click on 'Use this template' and select Create new repository.
![CH 04_001](https://private-user-images.githubusercontent.com/5276337/251956814-b477028d-f939-454a-9f9b-1b326261e06f.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjM4NDYxNTQsIm5iZiI6MTcyMzg0NTg1NCwicGF0aCI6Ii81Mjc2MzM3LzI1MTk1NjgxNC1iNDc3MDI4ZC1mOTM5LTQ1NGEtOWY5Yi0xYjMyNjI2MWUwNmYucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI0MDgxNiUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNDA4MTZUMjIwNDE0WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9NGM4MjNhNzdlODQyOTYxMDgxYmQwMTU1OTcwZDg2YzI5NWU5YjkwZGRiNjNkMjBkYjIyNTZmZjI3OWM4YWY4MSZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmYWN0b3JfaWQ9MCZrZXlfaWQ9MCZyZXBvX2lkPTAifQ.4XHXqjSsi3fSobDel3SF2s8DiAm1qQiR7AsUmMJPJRE)
Pick your GitHub username as the owner and enter MyActionInAction
as the repository name. Make the repository public and click Create repository from template
.
![CH 04_002](https://private-user-images.githubusercontent.com/5276337/251956868-3f1a0b86-8b4d-4523-a2bd-d0e19054caac.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjM4NDYxNTQsIm5iZiI6MTcyMzg0NTg1NCwicGF0aCI6Ii81Mjc2MzM3LzI1MTk1Njg2OC0zZjFhMGI4Ni04YjRkLTQ1MjMtYTJiZC1kMGUxOTA1NGNhYWMucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI0MDgxNiUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNDA4MTZUMjIwNDE0WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9NDNhNTBhMDQ3MTBlODc1ZTI3MzBlYzdhMGRhMjIxZDNkZmIyNDhhZDg3ZWQ4NmZiYjA3ZTNhNDQ4NTU1MThkZCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmYWN0b3JfaWQ9MCZrZXlfaWQ9MCZyZXBvX2lkPTAifQ.Y9ciSWeaTy3XCRGb2RTPXzKxpLAZ6YidNn8ln8hNbMk)
Create a new file called `Dockerfile``. Add the following content:
# Container image that runs your code
FROM alpine:latest
# Copies your code file from your action repository to the filesystem path '/' of the container
COPY entrypoint.sh /entrypoint.sh
# Make the script executable
RUN chmod +x entrypoint.sh
# Code file to execute when the docker container starts up ('entrypoint.sh')
ENTRYPOINT ["/entrypoint.sh"]
The dockerfile defines the docker container for the action. You could also use an existing image, but we want to build everything from scratch. We use the latest alpine image and just copy a simple shell script into the container.
Commit the file.
Create a new file called action.yml
. Add the following content and replace the placeholder {GitHub username}
with your GitHub user name:
name: "{GitHub username}'s Action in Action"
description: 'Greets someone and returns always 42.'
inputs:
who-to-greet: # id of input
description: 'Who to greet'
required: true
default: 'World'
outputs:
answer: # id of output
description: 'The answer to everything (always 42)'
runs:
using: 'docker'
image: 'Dockerfile'
args:
- ${{ inputs.who-to-greet }}
This action file defines the action and the input and output parameters. The runs
section is the part that defines the action type - in this case we use docker
together with a Dockerfile
instead of an image.
Commit the file.
Create a new file called entrypoint.sh
. Add the following content:
#!/bin/sh -l
echo "Hello $1"
echo "answer=42" >> $GITHUB_OUTPUT
The script just writes Hello
and the input parameter who-to-greet
to the console and sets the output parameter answer
to 42.
The action is now ready to be used. To see it in action, we'll create a workflow that uses it. Create a new file called .github/workflows/test-action.yml
. Add the following content:
name: Test Action
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout repo to use the action locally
uses: actions/[email protected]
- name: Run my own container action
id: action
uses: ./
with:
who-to-greet: '@wulfland'
- name: Output the answer
run: echo "The answer is ${{ steps.action.outputs.answer }}"
- name: Test the container
if: ${{ steps.action.outputs.answer != 42 }}
run: |
echo "::error file=entrypoint.sh,line=4,title=Error in container::The answer was not expected"
exit 1
The workflow will automatically run and execute the action. Inspect the output. You can see that the container was created and outputs th egreeting to the workflow log. The otput parameter can be access in subsequent steps.
![CH 04_003](https://private-user-images.githubusercontent.com/5276337/251960278-e6d2cbc6-186b-4093-9f63-d6bc31bace75.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjM4NDYxNTQsIm5iZiI6MTcyMzg0NTg1NCwicGF0aCI6Ii81Mjc2MzM3LzI1MTk2MDI3OC1lNmQyY2JjNi0xODZiLTQwOTMtOWY2My1kNmJjMzFiYWNlNzUucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI0MDgxNiUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNDA4MTZUMjIwNDE0WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9OThiYTA1ZTI5NWU2MzUwOGUxMGY3NDc3NGI5YmY3Yjk1NDJhYjMzOWNkOGU2ZjFiNGQwYzRkNDA3MDhkYzUxYSZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmYWN0b3JfaWQ9MCZrZXlfaWQ9MCZyZXBvX2lkPTAifQ.0mAwpvI9PJkVR0XOhoqsqt2_nPS-tH6ReRZsN82KNYU)