3 minutes
Utilizing Github Actions to Serve a tool via Web
TL;DR: I employed GitHub Actions to execute a Go utility, essentially utilizing GitHub Actions as a server to serve my Go tool via a Web interface.
Just for fun, I wanted to serve one of my Go tools gh-archive through a web interface. After some thought, I decided to make use of (or exploit) GitHub Actions.
Strategy:
- Gather user input through an HTML form (hosted via GitHub pages).
- Trigger a dispatch event to create a workflow in GitHub with a unique name.
- The GitHub Workflow will perform the tasks of building, running, and saving the output file of the Go program.
- Retrieve the list of all workflow and iterate through the JSON results to match the workflow name.
- Check the status of that workflow, if it’s completed or not.
- If the workflow status is completed, retrieve the downloadable URL of the artifacts, download, and extract them.
- Display the content extracted from the output file back to the user.
To execute these steps, I skimmed through the GitHub REST API Documentation to identify the necessary APIs for the tasks at hand.
GitHub Workflow:
name: Go
run-name: "${{ github.event.inputs.run_id }}"
on:
workflow_dispatch:
inputs:
topic:
description: 'Repository topic'
required: true
repo:
description: 'Number of repositories to check'
required: false
run_id:
description: 'Workflow name'
required: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Fetch Go Program Repository
run: git clone https://github.com/iamnihal/gh-archive.git gh-archive
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.21.3'
- name: Build
run: go build -v -o main .
working-directory: ./gh-archive
- name: Run
run: ./gh-archive/main -t "${{ github.event.inputs.topic }}" -n "${{ github.event.inputs.repo }}" -o ./gh-archive/output.txt
- name: Save Output
uses: actions/upload-artifact@v2
with:
name: go-output
path: ./gh-archive/output.txt
access-artifact:
needs: build
runs-on: ubuntu-latest
steps:
- name: Download Artifact
uses: actions/download-artifact@v2
with:
name: go-output
path: ./downloaded-artifact
- name: Print Contents
run: |
cat ./downloaded-artifact/output.txt
The workflow is pretty much self-explanatory. The workflow is triggered by a manual dispatch event (workflow_dispatch), allowing the user to input values such as the repository topic, the number of repositories to check (repo), and the workflow name (run_id). Then it goes on to set up Go, building, running, and saving the output file of the Go program to the GitHub storage.
index.html
Click here to view the HTML source code.
Within the HTML file, there are two crucial JavaScript functions:
triggerWorkflow(topic, repo)
- This function initiates a dispatch event to GitHub Actions, subsequently retrieving the list of all workflow runs for a repository. It then matches the “run_id” to identify the corresponding workflow run.
APIs:
/repos/OWNER/REPO/actions/workflows/WORKFLOW_ID/dispatches
/repos/OWNER/REPO/actions/runs
checkWorkflowCompletion()
- This function retrieves details about a specific workflow run to assess its completion status. If the status is “completed,” it proceeds to download the artifacts, unzip them, perform JSON parsing, and present the results to the user.
APIs:
/repos/OWNER/REPO/actions/runs/RUN_ID
/repos/OWNER/REPO/actions/runs/RUN_ID/artifacts
demo
You can try it here https://iamnihal.github.io/gh-archive-web/