Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/davealdon/pr-artifact-comments

πŸ€–πŸ¦ΎπŸ¦Ώ An example of how to add automated Github Action comments to PRs with artifacts download links
https://github.com/davealdon/pr-artifact-comments

actions artifact automation download github github-actions pr

Last synced: 22 days ago
JSON representation

πŸ€–πŸ¦ΎπŸ¦Ώ An example of how to add automated Github Action comments to PRs with artifacts download links

Awesome Lists containing this project

README

        

# PR Artifact Comments

This repo demonstrates how to use GitHub Actions to automatically comment on a PR with a download link to the artifact produced by the workflow.

![](/assets/banner.png)

## Description

In the pursuit of perfect automation, having build artifacts from Github pipelines be available at your fingertips is an impressive quality-of-life improvement for developers. If you've used Github Actions, you know that build artifacts are easily accessible to download after drilling down into an individual workflow run. But when you're reviewing code in a PR, this requires three clicks from a code review going to Actions -> Build -> Download Artifact.

![](/assets/actions.png)

I've always wanted to get this click count down to one, and in this post, I'll show you how I did it.

After setting up this Github Action, you'll have a fully automated comment on your PR with a download link to all of the individual artifacts produced by the workflow!

![](/assets/comment.png)

## When This Really Shines

Some people believe that going from three clicks to one isn't justifiable for the effort required. But really, any automation task is looking at the long-run. If you're only dealing with a single artifact, then sure, it may not be necessary. But on projects where you need multiple artifacts produced, and multiple actions running them, this consolidates your artifacts into a single PR comment.

For example, with React Native projects, in a production environment we're dealing with at least four artifacts:

1. Simulator `.app` build for iOS
2. Distribution `.ipa` build for iOS
3. Testing `.apk` build for Android
4. Distribution `.aab` build for Android

In my case, I use in-house runners to kick off iOS builds, and Github cloud runners for Android. These can both run in parallel, but the artifacts end up in different runs. Instead, through automation, we can get all of these artifacts into a single PR comment that self-updates with the asynchronous workflow runs.

You can see an example of this in action in [this PR](https://github.com/DaveAldon/PR-Artifact-Comments/pull/2).

## How it works

You may be thinking that you could just use an existing action from the Github marketplace to do this. And there may be some that work, but I've had no such luck, and I don't want to pay for anything. So starting with that assumption, let's begin by inspecting what an artifact really is. All we need is a link to the artifact, so let's take a look at one:

`https://github.com/DaveAldon/PR-Artifact-Comments/actions/runs/9454394757/artifacts/1586896203`

This link is broken down into three parts:

1. The repo reference: `DaveAldon/PR-Artifact-Comments`
2. The workflow run ID: `9454394757`
3. The artifact ID: `1586896203`

Sounds easy enough, right? The repo reference and workflow run id is actually really easy to get during a given action run, and are available through the Github [context API](https://docs.github.com/en/actions/learn-github-actions/contexts). For example, run id can be retrieved at any point like this:

```yaml
steps:
- name: Print Workflow Run ID
run: echo "The workflow run ID is ${{ github.run_id }}"
```

But notice in the docs that getting any artifact ids is missing? You can actually retrieve them via the [REST API](https://docs.github.com/en/rest/actions/artifacts?apiVersion=2022-11-28), but the artifact link only lasts one minute and only works after the run has finished. It's not possible using this method to pull the artifact ID during the run itself. Also, I'm expecting to kick off my runs and come back a while later hoping to download whatever I want, whenever I want. Not within one minute.

So what I've done is use the Github API to its fullest, and inject code into the action process in order to get the id. Here's how to do it:

1. When you upload your artifact, bind it to an id:

```yaml
- name: Upload Artifact
uses: actions/[email protected]
id: sample-artifact
with:
name: sample-artifact
if-no-files-found: error
retention-days: 14
path: ${{ github.workspace }}/sample.txt
```

2. Use the `id` field to assign the artifact id to a temporary environment variable:

```yaml
- name: Output artifact ID
run: echo "SAMPLE_ARTIFACT_ID=${{ steps.sample-artifact.outputs.artifact-id }}" >> $GITHUB_ENV
```

3. Reference the environment variable inside a script job to build the link and initiate the PR comment:

```yaml
- name: Comment PR
uses: actions/[email protected]
if: success()
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
const sample_artifact_id = process.env.SAMPLE_ARTIFACT_ID;

const issue_number = context.issue.number;
const run_id = context.runId;
const repo = context.repo;

// Merges to main branch do not have an associated issue number
if(!issue_number) {
return;
}

const development_link = `https://github.com/${repo.owner}/${repo.repo}/actions/runs/${run_id}/artifacts/${sample_artifact_id}`

const comment = `
## βœ… Build Artifacts 😍

| Build Name | Download Link |
| --- | --- |
| 🌎 Artifact Download | [Download](${development_link}) |
`;

// Create a new comment
await github.rest.issues.createComment({
owner: repo.owner,
repo: repo.repo,
issue_number: issue_number,
body: comment
});
```

And voila! Whenever you make a PR, the action will run, upload the artifact, and comment on the PR with a download link to the artifact. Another added bonus is that when an action comments on your PR, you'll get an email with the contents, meaning that you can download your artifacts from emails too!

![](/assets/email.png)

You can take a look at the example in [this repo](https://github.com/DaveAldon/PR-Artifact-Comments) which has even more code in the build script that handles:

1. Creating a comment template with "in progress" statuses for other asynchronous actions
2. Searches for a bot comment and replaces it with the new download link