# Local testing GitHub Actions

**URL:** <https://anchorecommunity.discourse.group/t/local-testing-github-actions/51>\
**Category:** General\
**Created:** [July 22, 2024, 12:07pm UTC](https://anchorecommunity.discourse.group/t/local-testing-github-actions/51 "2024-07-22T12:07:25Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![popey](https://yyz2.discourse-cdn.com/free1/user_avatar/anchorecommunity.discourse.group/popey/32/429_2.png) [@popey](https://anchorecommunity.discourse.group/u/popey)\
**Post date:** [July 22, 2024, 12:07pm UTC](https://anchorecommunity.discourse.group/t/local-testing-github-actions/51/1 "2024-07-22T12:07:25Z")

</div>

Last week, somewhere I recall someone (maybe @kzantow ) suggesting that there might be use in being able to iterate on, and debug GitHub actions locally, rather than wait for the GitHub runners. I suspect this was in the context of a bug, but this week’s brain has swapped out last weeks context, sorry.

Anyway, I just stumbled on [act](https://github.com/nektos/act) which may be of use. It’s a tool written in Go which does pretty much what you expect. It leverages your local Docker setup to spin up GHA-like containers in which to run the actions.

As a test I grabbed [sbom-action](https://github.com/anchore/sbom-action) to give it a shake. I’m using an M1 mac, so it recommended I add the `--container-architecture linux/amd64` and pointed it at the `test.yml` action, thus:

`act -W ./.github/workflows/test.yml --container-architecture linux/amd64`

Any of you lot tried this before? It’s super quick (on my M3 Pro), feels pretty handy, and could speed up some iteration, assuming the tests work locally in docker.

Here’s the top of the output:

```plaintext
INFO[0000] Using docker host 'unix:///var/run/docker.sock', and daemon socket 'unix:///var/run/docker.sock'
[build-test/build] 🚀 Start image=catthehacker/ubuntu:act-latest
[build-test/test-as-action] 🚀 Start image=catthehacker/ubuntu:act-latest
[build-test/test] 🚀 Start image=catthehacker/ubuntu:act-latest
[build-test/test-on-fixture-dirs-2] 🚧 Skipping unsupported platform -- Try running with `-P ubuntu-latest=...`
[build-test/test-on-fixture-dirs-1] 🚀 Start image=catthehacker/ubuntu:act-latest
[build-test/build] 🐳 docker pull image=catthehacker/ubuntu:act-latest platform=linux/amd64 username= forcePull=true
[build-test/test-as-action] 🐳 docker pull image=catthehacker/ubuntu:act-latest platform=linux/amd64 username= forcePull=true
[build-test/test-on-fixture-dirs-1] 🐳 docker pull image=catthehacker/ubuntu:act-latest platform=linux/amd64 username= forcePull=true
[build-test/test] 🐳 docker pull image=registry:2 platform=linux/amd64 username= forcePull=true
[build-test/test] 🐳 docker pull image=catthehacker/ubuntu:act-latest platform=linux/amd64 username= forcePull=true
[build-test/build] 🐳 docker create image=catthehacker/ubuntu:act-latest platform=linux/amd64 entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"

```

Here’s the bottom of the output:

```plaintext
| PASS tests/integration/GitHubSnapshot.test.ts
| GitHub Snapshot
| ✓ runs with default inputs (272 ms)
|
----------------------|---------|----------|---------|---------|---------------------------------------------------------------------------------------------------
| File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s                                                                            
| ----------------------|---------|----------|---------|---------|---------------------------------------------------------------------------------------------------
| All files | 88.11 | 75 | 91.42 | 88.33 |                                                                                              
| src | 100 | 100 | 100 | 100 |                                                                                              
| SyftVersion.ts | 100 | 100 | 100 | 100 |                                                                                              
| src/github | 86 | 72.32 | 89.47 | 86.3 |                                                                                              
| Executor.ts | 100 | 100 | 100 | 100 |                                                                                              
| GithubClient.ts | 82.03 | 54.16 | 89.28 | 82.25 | 107-111,157,168-169,305,384,388-389,419-420,447,454-457,477-490                              
| SyftGithubAction.ts | 87.89 | 77.27 | 92 | 88.18 | 65-66,124,134,148,193-194,205-210,220,246-247,289-290,420,429,433-436,509,535,545-546,563,590-593
| Util.ts | 66.66 | 100 | 0 | 66.66 | 4                                                                                            
| tests | 96.8 | 90 | 93.75 | 96.73 |                                                                                              
| mocks.ts | 96.8 | 90 | 93.75 | 96.73 | 90,155,208                                                                                   
| ----------------------|---------|----------|---------|---------|---------------------------------------------------------------------------------------------------
| Test Suites: 1 failed, 3 passed, 4 total
| Tests: 12 failed, 37 passed, 49 total
| Snapshots: 9 passed, 9 total
| Time: 18.588 s
| Ran all test suites.
[build-test/test] ❌ Failure - Main npm test
[build-test/test] ⚙ ::set-env:: ANCHORE_SBOM_ACTION_PRIOR_ARTIFACT=test-repo-a_job.cyclonedx.json
[build-test/test] ⚙ ::add-path:: /tmp/actions/cache/syft/1.9.0/x64
[build-test/test] ⚙ ::add-path:: /tmp/actions/cache/syft/1.9.0/x64
[build-test/test] ⚙ ::add-path:: /tmp/actions/cache/syft/1.9.0/x64
[build-test/test] ⚙ ::add-path:: /tmp/actions/cache/syft/1.9.0/x64
[build-test/test] ⚙ ::add-path:: /tmp/actions/cache/syft/1.9.0/x64
[build-test/test] ⚙ ::add-path:: /tmp/actions/cache/syft/1.9.0/x64
[build-test/test] ⚙ ::add-path:: /tmp/actions/cache/syft/1.9.0/x64
[build-test/test] ⚙ ::add-path:: /tmp/actions/cache/syft/1.9.0/x64
[build-test/test] ⚙ ::add-path:: /tmp/actions/cache/syft/1.9.0/x64
[build-test/test] ⚙ ::add-path:: /tmp/actions/cache/syft/1.9.0/x64
[build-test/test] ⚙ ::add-path:: /tmp/actions/cache/syft/1.9.0/x64
[build-test/test] ⚙ ::add-path:: /tmp/actions/cache/syft/1.9.0/x64
[build-test/test] ⚙ ::add-path:: /tmp/actions/cache/syft/1.9.0/x64
[build-test/test] ⚙ ::add-path:: /tmp/actions/cache/syft/1.9.0/x64
[build-test/test] ⚙ ::add-path:: /tmp/actions/cache/syft/1.9.0/x64
[build-test/test] ⚙ ::add-path:: /tmp/actions/cache/syft/1.9.0/x64
[build-test/test] ⚙ ::add-path:: /tmp/actions/cache/syft/1.9.0/x64
[build-test/test] ⚙ ::add-path:: /tmp/actions/cache/syft/1.9.0/x64
[build-test/test] ⚙ ::add-path:: /tmp/actions/cache/syft/1.9.0/x64
[build-test/test] ⚙ ::add-path:: /tmp/actions/cache/syft/1.9.0/x64
[build-test/test] exitcode '1': failure
[build-test/test] 🏁 Job failed

```

A useful tool for the armoury? Anyone else tried this?

(I did have to patch the workflow I used above, because port 5000 is in use by some macOS thing):

```diff
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 89aae24..48e53a9 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -62,14 +62,14 @@ jobs:
       registry:
         image: registry:2
         ports:
- - 5000:5000
+ - 5001:5000
     steps:
       - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
       - name: Build images
         run: |
           for distro in alpine centos debian; do
- docker build -t localhost:5000/match-coverage/$distro ./tests/fixtures/image-$distro-match-coverage
- docker push localhost:5000/match-coverage/${distro}:latest
+ docker build -t localhost:5001/match-coverage/$distro ./tests/fixtures/image-$distro-match-coverage
+ docker push localhost:5001/match-coverage/${distro}:latest
           done
       - run: npm ci
       - run: npm test

```

---

<div class="post-metadata">

**Author:** ![willmurphy](https://yyz2.discourse-cdn.com/free1/user_avatar/anchorecommunity.discourse.group/willmurphy/32/12_2.png) [@willmurphy](https://anchorecommunity.discourse.group/u/willmurphy)\
**Post date:** [July 22, 2024, 2:22pm UTC](https://anchorecommunity.discourse.group/t/local-testing-github-actions/51/2 "2024-07-22T14:22:26Z")

</div>

I had previously tried to set up `act`, and it seems to have remembered what images I was using, so I had to make a couple of changes to get this working. Specifically, I had to explicitly pass `-P ubuntu-latest=catthehacker/ubuntu:act-latest` or it was using to `node:16-buster-slim` which is both too old a Node and lacks the `git` cli.

I also had it hang on `git diff` and had to change the command to `git --no-pager diff` to prevent it from waiting for someone to page down in `less` I think.

Regarding port 5000, I think you might find that it’s actually a previous test run that is using port 5000, which is something we probably want to fix. @popey if you `docker ps`, is there a `registry:2` image listening on 5000?

When running this locally, I usually see a successful test run followed by a cryptic failure. For example, `Error: Job 'build' failed`. (I’ve seen other job failures as well, such as `Error: Job 'test-as-action' failed`. I’m not sure what to make of these failures being printed later. Is that others’ experience with this test setup? It would be nice if it ran the whole workflow and exited zero 🙂

I was _also_ trying to make local and GHA testing of sbom-action more similar, and had opened a [small PR](https://github.com/anchore/sbom-action/pull/476), but GHA runs the local registry as a service, rather than as an imperative part of the tests, which might be preferable for a reason I’m not thinking of.

---

<div class="post-metadata">

**Author:** ![popey](https://yyz2.discourse-cdn.com/free1/user_avatar/anchorecommunity.discourse.group/popey/32/429_2.png) [@popey](https://anchorecommunity.discourse.group/u/popey)\
**Post date:** [July 22, 2024, 5:21pm UTC](https://anchorecommunity.discourse.group/t/local-testing-github-actions/51/3 "2024-07-22T17:21:02Z")

</div>

Would you believe, it’s [AirPlay Receiver](https://nono.ma/port-5000-used-by-control-center-in-macos-controlce) that’s taking port 5000!

 ![Screenshot 2024-07-22 at 18.18.18](https://global.discourse-cdn.com/free1/uploads/anchorecommunity/original/1X/7f9a22ac955ec8916371f4098585bc7c9b73cde3.jpeg)

vs

 ![Screenshot 2024-07-22 at 18.19.06](https://global.discourse-cdn.com/free1/uploads/anchorecommunity/original/1X/d1ff23a7f955bf270192a8dff6a4c027ba4455c7.jpeg)

🤯
