I created a custom Github action that deploys a static website to s3, and I want to point out a few details of my process of building a reusable action.
For detailed reference refer to https://docs.github.com/en/actions/creating-actions/about-custom-actions.
There are 3 types of custom actions - docker, javascript and composite.
For deploying to S3 I decided to go with a composite action. There's already an existing action that I can reuse for aws cli.
Starting point
action.yaml
is the main file for a custom Github action.
Refer to https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions for other supported metadata.
action.yaml
name: "Deploy static website to S3"
description: "Deploys static website to S3 without html extension. Works for NextJS."
author: "Ana Bujan - Eisberg Labs"
runs:
using: "composite"
steps:
- uses: unfor19/install-aws-cli-action@v1
- run: ${{ github.action_path }}/deploy-doc-to-s3.sh "${{inputs.target}}" "${{inputs.exclusions}}" "${{inputs.bucket}}" "${{inputs.dest}}"
shell: bash
inputs:
target:
description: 'Location of static website'
required: false
default: ''
exclusions:
description: 'Regex pattern for files to be excluded from extension removal'
required: false
default: ''
bucket:
description: 'Bucket name'
required: true
dest:
description: 'Destination directory path'
required: true
branding:
icon: "upload-cloud"
color: "blue"
This composite action combines 2 workflow steps into a single step:
- installing aws cli that I can use in the next step
- running the bash script that takes target, exclusions, bucket and dest inputs.
Invoking bash scripts
If invoking bash scripts on your action, do not start with ./script.sh
! It will only work on your action repository. Other repositories will report that the script is missing.
My first draft had a ./deploy-doc-to-s3.sh
instead of ${{ github.action_path }}/deploy-doc-to-s3.sh
.
Branding
Branding defines a badge icon that shows up next to your custom action. Supported icons are https://feathericons.com/.
Inputs
Arguments that action expects in the runtime are defined in inputs
field. In a composite action they are only accessible with ${{inputs.<variable_name>}}
. All other actions can access input variables also through environment variable INPUT_<VARIABLE_NAME>
.
When using this kind of action, inputs are defined in with
map of the input parameters:
- name: Deploy to s3 uses: eisberg-labs/static-website-to-s3@main with: target: nextjs-testapp/out dest: next-to-s3/nextjs-testapp exclusions: ^nextjs-testapp\/out\/(index).html$ bucket: ${{ secrets.BUCKET }}
Test the workflow
Before syncing the action to Github, I like to test it locally and I'm able to do so with https://github.com/nektos/act.
Install act
curl https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash
My usual commands
As for the usual commands, I mostly use act -l
for listing of the available jobs, act -j <job_name>
-s <your_secret>.
Typing just act
will default to jobs that are triggered on push
.
When first working on a repo that will be open sourced, I like to work on a private repository first.
Reason being, I don't want you to see the mess I'm making on my repo, force-pushing to main, rebasing etc. And when I'm ready, private repo becomes public.
To test private Github actions on nektos act, you have to authenticate. Otherwise this happens:
Unable to clone https://github.com/... refs/heads/main: authentication required
Create a personal Github access token and use like act -s GITHUB_TOKEN=<your_token>
.
Publish to Github marketplace
When you're ready to publish your action:
- Go to releases
- Draft a new release
- Click on checkbox Publish this Action to the GitHub Marketplace
- Tag your release, document changelog and publish release.