Joshua's Docs - GitHub Actions - Notes, Tips, and Resources
Light

Resources

What & Link Type
GitHub: GitHub Actions Docs
- Workflow Syntax Reference
Official Docs
GitHub: Actions Cheat Sheet
- Source Code
Cheatsheet
github.com/actions
- Starter Workflows
Tools and samples around Actions
Jason Etcovitch:
- What are Workflows
Jason has some of the best posts around on GitHub actions; incredible level of depth and explains concepts on multiple levels.
Gabriel Tanner: An Introduction to GitHub Actions Introduction / Cheatsheet
sdras/awesome-actions Collection of resources / links
G Adventures: Things I learned making my first Github Action Step-by-step example of making a custom action. Focuses on Bash scripting side.

GitHub Actions - FAQ

  • Where can I find the default environment variables that are injected into actions?
  • Workflows vs actions?
    • Workflows are at the highest level of Github Actions - a workflow can contain all the sub-components of Github Automation pieces
    • Workflow -> [Job] -> [Step] -> [Action (GH, or Docker), Task, or Command (e.g. run)]
    • The best diagram I have found (so far) that clearly shows this, is this one, from this article.
  • How do I run multiple commands under a single run step?
    • Use a pipe (|) right after run: , and then indent each command line below it. Example.
    • If you want to split into multiple lines, but not execute each line (e.g., all one long command), use \ at EOL to mark as continuation
  • How do I get a nice badge image based on actions?
    • Docs: Adding a workflow status badge
    • Summary: The URL syntax is one of...:
      • Whether or not workflow has name: https://github.com/<OWNER>/<REPOSITORY>/actions/workflows/<WORKFLOW_FILENAME>/badge.svg
      • If workflow has name: https://github.com/<OWNER>/<REPOSITORY>/workflows/<WORKFLOW_NAME>/badge.svg
    • Remember URL encoding
  • How do I use secrets / passwords / .env vars?
    1. Add them under Repo -> Settings -> Secrets
    2. Within a workflow .yml file, pull in the secret with this syntax:
      • ${{ secrets.SECRET_NAME }}
  • Security: How do I keep my actions and workflows safe?
  • How do I know how many minutes my workflows have used? How many I have left?
  • What is the purpose of things like echo "::debug::hello world"
  • How do I use variables in the jobs.{ID}.container? For example, using GITHUB_WORKSPACE in volumes to map an absolute path of the host to a docker path?

Different Ways of Using Containers

The relationship of GitHub Actions to VMs (Virtual Machines), Docker, and Containers is not always straightforward, and has also evolved over time.

At a basic level:

  • Each job runs on a VM (Virtual Machine), specified by the runs-on parameter
  • Each step can run either directly on the VM, or inside a container
  • For steps that use an action, via the uses parameter, those also run in a container, dictated by the source code of the action being pulled in

🔗 This StackOverflow response does a good job of summarizing this relationship with example YAML.

Pushing Commits in an Action

In addition to producing build artifacts, GitHub Actions can actually make new commits on your behalf, and push them to your repo. Common uses cases for this are:

  • Automatically linting / formatting code and committing with fixes applied
  • Committing generated build artifacts to the repository
  • Auto-updating docs
  • Branches used only for deploys (e.g. for GitHub Pages)

GitHub even provides a secure mechanism to streamline this; at the start of each workflow, a short-lived authentication token is provisioned and injected into the environment (the GITHUB_TOKEN), which can be used throughout the lifetime of the specific workflow.

Furthermore, there is an action that streamlines the process of interacting with git from within the action even further: the actions/checkout action. In addition to checking out your code into the action's volume, this action also handles some automatic setup, so that the authentication token is used by the instance of git on the VM (it is persisted); you only need to manually reference the token if you are using a different remote. For example, the docs for actions/checkout provide an example use-case for pushing a new commit, which only takes about 5 lines of actual shell code.

If you are not using actions/checkout, need to use a nested git repository, or want to manually configure a git push, here is a sample of how you might approach it:

steps:
  - name: Push New Branch
    run: |
      GIT_ORIGIN="https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY.git"
      git init
      git config user.name "${GITHUB_ACTOR}"
      git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
      git remote add origin $GIT_ORIGIN
      git add .
      git commit -m "Auto-Commit, from $GITHUB_SHA"
      git checkout -b $NEW_BRANCH_NAME
      git push origin HEAD:$NEW_BRANCH_NAME

GitHub Actions - Tips, Tricks, and Pitfalls to Avoid

  • Forgetting to use cd or working-directory to make sure steps execute in the correct directory
    • For run steps, you can use the standard cd command to traverse directories as part of the step, or pass the starting directory directly, with working directory
    • At the job level, you can set a default working-directory for all run steps within that job
  • Be careful about infinite loops via triggers
  • A ton of issues around file permissions and use access can be fixed by correctly using chown and chmod between steps
    • Especially since GitHub uses a special passwordless root user

Passing Data Around Between Steps, Actions, and Environments

There are multiple ways that data can be passed around in GitHub actions, and it really depends on which actions are being used and the specific context. Some common options:

To pass variable values between steps in the same job, you don't have to use artifacts, but you still do need a special syntax:

  • Setting shared environment variables
    • echo "{environment_variable_name}={value}" >> "$GITHUB_ENV"
  • Using explicit outputs
    • In the step that produces the output, give the step a unique id, and then inside your run command, use:
      • echo "{name}={value}" >> "$GITHUB_OUTPUT"
    • In the step that uses the previous output, you can reference the output value by step ID and name:
      • ${{ steps.YOUR_STEP_ID.outputs.YOUR_OUTPUT_NAME }}

act for Local GitHub Action Running

act (nektos/act) is a tool for running GitHub actions locally, with minimal setup required. It is not a perfect 1:1 mirror of how GitHub actions execute through the hosted runner, but is still very useful.

GitHub Actions - ACT - How Do I...

  • How to watch what ENV variables each step runs with
    • Enable verbose logging, with --verbose, optionally in dry-mode, with --dry-run
  • Inspect the local bin of a 3rd party action that is being used?
    • You could either inspect the overall ACT Docker container, or if the action was built as a separate container, that one instead
    • Inspecting is a little complicated; you might have to mount the image or dump it to a tarball in order to inspect the contents.

GitHub Actions - ACT - Issues

  • Cannot copy files to local system
    • This will not work: cp -r ./docker-dir ${GITHUB_WORKSPACE}; you are still in the docker container
    • Have to use volumes to share data
  • Any action that uses the cache fails, usually with getCacheEntry failed: Cache Service URL not found, unable to restore cache, or any action that uses artifacts fails
    • This has been a known issue for a while, but has seen recent activity that could address it - asset server implementation code (PR #677)
    • Main tracking issues: #329, #169
    • Until this is officially addressed, here are two workarounds
      • Use GitHub YML conditionals to skip a step if executed locally with ACT and all it does is cache (suggested here)
        • Conditional: if: ${{ !env.ACT }}
        • You can use ACT's --reuse flag to reuse the container, if you are after a faster run (suggested in #285)
      • Use the artifact server developed separately (anthonykawa/artifact-server), run it alongside ACT, and point ACT to it (like this)
Markdown Source Last Updated:
Sun Nov 12 2023 05:26:03 GMT+0000 (Coordinated Universal Time)
Markdown Source Created:
Sun Aug 01 2021 21:01:12 GMT+0000 (Coordinated Universal Time)
© 2024 Joshua Tzucker, Built with Gatsby
Feedback