{"id":15022214,"url":"https://github.com/stevenacoffman/commentary","last_synced_at":"2026-01-28T11:33:41.793Z","repository":{"id":43737519,"uuid":"460611670","full_name":"StevenACoffman/commentary","owner":"StevenACoffman","description":"Benchmark 5 ways to write GitHub Action in Go","archived":false,"fork":false,"pushed_at":"2022-02-22T20:05:04.000Z","size":573,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-02-15T17:36:43.817Z","etag":null,"topics":["github-actions"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/StevenACoffman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-02-17T21:20:02.000Z","updated_at":"2022-04-04T15:49:54.000Z","dependencies_parsed_at":"2022-09-26T16:22:06.009Z","dependency_job_id":null,"html_url":"https://github.com/StevenACoffman/commentary","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StevenACoffman%2Fcommentary","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StevenACoffman%2Fcommentary/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StevenACoffman%2Fcommentary/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StevenACoffman%2Fcommentary/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/StevenACoffman","download_url":"https://codeload.github.com/StevenACoffman/commentary/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239895242,"owners_count":19714792,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["github-actions"],"created_at":"2024-09-24T19:57:39.247Z","updated_at":"2026-01-28T11:33:41.740Z","avatar_url":"https://github.com/StevenACoffman.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"### Commentary - Update a GitHub comment\n\nThis is a small demo that will either create a new comment or update an existing comment\non a pull request in GitHub.\n\nI got the idea from [Ben Limmer](https://benlimmer.com/2021/12/20/create-or-update-pr-comment/), but I did it in Go.\n\nThis seemed like a good way to test how fast the various methods of running GitHub actions authored in Go would be.\nMy theory was that npm had an unfair advantage as it was already baked into the standard runner OS, but (SPOILER) I was wrong!\n\n### GitHub Actions - Many Ways to Go!\n\nAlthough a GitHub Action Ubuntu Runner comes with scripting languages like Bash, NodeJS, Python, etc.\nit doesn't come with Go 😞. Maintaining code is enough work in a single language _without_ \nhaving to also maintain tooling written in a _different_ language, with a _different_ ecosystem.\nAs a result, achieving quick feedback via GitHub Actions _**written in Go**_, is all about\nminimizing data transfer size in order to execute your written-in-Go step with as little wasted setup time as possible.\n\nSo to execute GitHub Action steps _**written in Go**_, I'm aware of these possibilities:\n1. Setup Go in the action, and then just shell out and `go run main.go`\n2. [package the Go using npm](https://github.com/sanathkr/go-npm) and further tweaked [like this](https://blog.xendit.engineer/how-we-repurposed-npm-to-publish-and-distribute-our-go-binaries-for-internal-cli-23981b80911b) (private or public npm registry as you please)\n3. [package your Go as a docker container](https://www.sethvargo.com/writing-github-actions-in-go/) (private or public registry)\n4. attach pre-built Go artifacts to a GitHub release and YOLO it (download and execute artifact via shell)\n5. [attach pre-built Go artifacts to a GitHub release and run those using JS wrappers](https://full-stack.blend.com/how-we-write-github-actions-in-go.html)\n\nI have started to add all these methods to this demo repository to see how they perform. So far I'm done with the first 4, but I imagine the Node wrapper would be the\nsame as the YOLO Bash one if the node script has no need to install npm dependencies.\n\n| Which Runner    | Elapsed | Download Size |\n|-----------------|---------|---------------|\n| YOLOCommenter   | 3s      | 2.92 MB       |\n| DockerCommenter | 4s      | 10 MB         |\n| NodeCommenter   | 6s      | 41 MB         |\n| GoRunCommenter  | 25s     | 134 MB        |\n\nThe overhead of having to download a Go environment makes `go run main.go` the slowest, but if your action needs the Go tools anyway,\nmaybe that doesn't add anything. `go run main.go` is certainly the simplest and easiest to maintain.\n\nYou can also use the `actions/cache@v2` or ([actions-go/toolkit/cache](https://github.com/actions-go/toolkit/tree/main/cache) in Go ) to further reduce subsequent startup time in all these cases.\n\n### Running as a GitHub Action\nThere are several environment variables that this needs.\n+ `COMMENTARY_ACTION_TYPE` -  you can have multiple actions all racing without stepping on each other\n+ `GITHUB_TOKEN` - This should be a secret, but is the personal access token of the service account (or your real GitHub account)\n+ `GITHUB_REPOSITORY` - Set by GitHub as an `owner/repo`\n+ `GITHUB_REPOSITORY_OWNER` - Set by GitHub as `owner` \n+ `GITHUB_BASE_REF` - Set by GitHub as `main`\n+ `GITHUB_HEAD_REF` - Set by Github to be the branch name, e.g. `mybranch`\n+ `GITHUB_REF_NAME` - Set by Github, for example, `1/merge`\n+ `GITHUB_SHA` - Set by GitHub as the commit sha1, and used to look up the PR.\n\n### Publishing your Go to ... NPM?\nAfter you (er... me?) cut a new release, you (I?)  need to increment the package.json `version` to match,\nand then run `npm publish`. If you get a 404, you might need to `npm login` again.\n\nThis Go-published-to-NPM idea was pioneered by [Sanath Kumar Ramesh](https://github.com/sanathkr/go-npm) and further tweaked [like this](https://blog.xendit.engineer/how-we-repurposed-npm-to-publish-and-distribute-our-go-binaries-for-internal-cli-23981b80911b).\n\nMy silly npm package is [commentary-cli](https://www.npmjs.com/package/commentary-cli) has a 39.44 MiB tar ball. \n\n### Publishing to Docker\nAfter you cut a new release, you need to push to Docker Hub. There's a handy ko.sh script\nthat will do it for you (er... me?) until I Go-ify it into the `magefile.go`.\n\nThis uses the excellent [`google/ko`](https://github.com/google/ko) to make a fairly small 10 MB image [over here](https://hub.docker.com/repository/docker/stevenacoffman/commentary)\n\n### YOLO style shell script to Run from release binary\nReally shell code should only be used for boot-strapping to something sane (like Go), so that's exactly what\nI am doing here.\n\nDownloading a tar.gz file from the latest release, extracting just the executable binary, running the executable\nis just complicated enough that I don't know how to do it in a short, one line shell script. (I imagine there's a trick to do it)\n\nThe installation instructions for a lot of things (e.g. homebrew) have you download and execute a shell script, which\nseems wildly insecure, so I've heard it referred to it as \"YOLO\" style installation (\"You Only Live Once\"). \n\nThere's a script `./download-extract-execute-artifact.sh` that downloads, extracts, and executes the binary artifact.\n\nThere's also a more complicated version of that in `./godownloader.sh` which is generated by [godownloader](https://github.com/goreleaser/godownloader).\n\n### Mage\n\nInstead of `make` and `Makefile`, I used [mage](https://magefile.org/) and made a [magefile](https://github.com/StevenACoffman/teamboard/blob/main/magefile.go).\n\nIf you do `brew install mage` then you can run here:\n+ `mage -v run` - will run the webserver by doing `go run main.go`\n+ `mage generate` - will re-generate the genqlient code by doing `go generate ./...`\n+ `mage install` - will build and install the commentary application binary\n+ `mage release \u003cv0.?.0\u003e` - will generate a new release using Go releaser\n\nOr just run the go commands by hand.\n\n### Stuff inside Commentary\nI use [genqlient](https://github.com/Khan/genqlient) to communicate with the GitHub GraphQL API.\nI used [Cobra](https://github.com/spf13/cobra) to scaffold out the cli.\nI use [Mage](https://github.com/magefile/mage) for task automation.\n\n### More GitHub Action in Go reading\nI mean to go back and read more of this:\n+ https://github.com/embano1/ci-demo-app/blob/main/DETAILS.md\n+ [sethvargo/go-githubactions](https://github.com/sethvargo/go-githubactions) - Go SDK for GitHub Actions\n+ [actions-go/toolkit](https://github.com/actions-go/toolkit) - Go SDK for GitHub Actions\n+ Run your GitHub Actions locally with [Act](https://github.com/nektos/act)\n+ [ChristopherHX/github-act-runner](https://github.com/ChristopherHX/github-act-runner) as self-hosted runner\n+ [rhysd/actionlint](https://github.com/rhysd/actionlint)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstevenacoffman%2Fcommentary","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstevenacoffman%2Fcommentary","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstevenacoffman%2Fcommentary/lists"}