Surfacing Gradle Build Scans Within GitHub Actions Workflows
Tags: ci, githubactions, gradle
Published: 2021-04-13 17:24:37

---
title: Surfacing Gradle Build Scans Within GitHub Actions Workflows
published: true
date: 2020-10-13 12:37:00 UTC
tags: continuousintegration,githubactions,gradle,ci
canonical_url: https://goobar.io/2020/10/13/surfacing-gradle-build-scans-within-github-actions/
---

This post demonstrates several approaches for surfacing Gradle build scans within [GitHub Actions](https://github.com/features/actions) workflows; thereby making them more discoverable and hopefully more useful to a team.

Recently, our Android team at [Premise Data](https://www.premise.com/) has worked with the [Gradle Enterprise](https://gradle.com/)team to optimize our Gradle builds.  Gradle build scans have been a key tool in this work.  Build scans have helped optimize our build, and have helped detect regressions and other build trends for both CI, and local developers’, builds.

Because of the value we’ve seen in regularly reviewing these build scans, I wanted a way to make these scans easier to find, and to use, for everyone on our team.

Table Of Contents

- [Working With Gradle Build Scans?](#working-with-gradle-build-scans)

  - [What are Gradle build scans?](#what-are-gradle-build-scans)
  - [What does a build scan look like?](#what-does-a-build-scan-look-like)
  - [How to generate a Gradle build scan?](#how-to-generate-a-gradle-build-scan)
  - [How to enable build scans for your Android project?](#how-to-enable-build-scans-for-your-android-project)
- [Surfacing Gradle Build Scan URLs as Pull Request Comments](#surfacing-gradle-build-scan-urls-as-pull-request-comments)

  - [Adding a Single Job’s Gradle Build Scan URL as a Pull Request Comment](#adding-a-single-jobs-gradle-build-scan-url-as-a-pull-request-comment)
  - [Adding Build Scan URL Comments for Multiple Jobs](#adding-build-scan-url-comments-for-multiple-jobs)
  - [Consolidating Multiple Job’s Build Scan URLs Into a Single Pull Request Comment](#consolidating-multiple-jobs-build-scan-urls-into-a-single-pull-request-comment)
- [Storing Gradle Build Scan URLs In GitHub Actions Workflow Artifacts](#storing-gradle-build-scan-urls-in-github-actions-workflow-artifacts)

  - [Writing Gradle Build Scan URLs to a File](#writing-gradle-build-scan-urls-to-a-file)
  - [Storing Build Scan Files as Workflow Artifacts](#storing-build-scan-files-as-workflow-artifacts)
  - [Storing Multiple Build Scan Files as a Single Workflow Artifact](#storing-multiple-build-scan-files-as-a-single-workflow-artifact)
- [Learn More](#learn-more)
- [Wrapping Up](#wrapping-up)

_Thanks to [Tony Robalik](https://twitter.com/AutonomousApps) for pointing me in the direction of adding build scan urls as PR comments._

## Working With Gradle Build Scans?

Before we dive in, let’s quickly review Gradle build scans; what are they, and [how to enable them](https://guides.gradle.org/creating-build-scans/) for your project?

<section><div></div>
<div>
<div><div><div>
<div>
<div><h3>Find the Code</h3></div>
<div><p>If you want to check out these full examples, you can find them on GitHub.</p></div>
</div>
<div><div><a href="https://github.com/n8ebel/GitHubActionsAutomationSandbox/compare/ne/buildscan-recipes" target="_blank" rel="noopener noreferrer"><span><span>Open In Github</span></span></a></div></div>
</div></div></div>
</div></section>
### What are Gradle build scans?

Gradle [build scans provide a detailed overview](https://gradle.com/build-scans/) of your Gradle build.  These details include a myriad of information including _tasks executed, build cache performance, test results, environment details,_ and much more.

### What does a build scan look like?

Build scans are presented as interactive webpages hosted at either `scans.gradle.com` or within your own Gradle Enterprise instance.

<section><div></div>
<div>
<div><p><img src="https://lh4.googleusercontent.com/d_dD9svW9pN1Zig5vXLb1FS-5xSE6TcXVN0nQdTPYnkXzVXlVZfI4QeCD0qQHy3IAMv-rWSfOUIDpMhxyjc_tZCMILrzavuQu3SC4KvlI7uh6DzeNMXotj02uksuw8_OtpaTgJZa" alt=""><figcaption>Sample build scan</figcaption></p></div>
</div></section>

When scans are generated for a build, a link to the build scan will be included at the end of the console build output.

### How to generate a Gradle build scan?

Generating a Gradle build scan for a single Gradle task execution is simple.  We only need to add the `–scan` option to our task invocation.

```
./gradlew assembleDebug --scan
```

At the end of this execution, we see the following in our console window:

```
Publishing build scan...[https://gradle.com/s/](https://gradle.com/s/)<scan id here>
```

It’s this url that I wanted to surface to our team.

### How to enable build scans for your Android project?

If your team is leveraging Gradle Enterprise, or you just want to generate build scans for all builds, you can integrate the Gradle Enterprise plugin into your project.

First, you’ll want to add the Gradle Enterprise plugin to your `settings.gradle` file. 

```
plugins { id "com.gradle.enterprise" version "3.4.1" }
```

Next, you can configure build scan behavior in your `settings.gradle` file.

```
gradleEnterprise { buildScan { termsOfServiceUrl = "https://gradle.com/terms-of-service" termsOfServiceAgree = "yes" publishAlways() } }
```

With this setup in place, a build scan will be generated for each build of your project. We took the time to review this setup because we’ll make use of this later on.

## Surfacing Gradle Build Scan URLs as Pull Request Comments

Now that we’re familiar with Gradle build scans, let’s return to the idea of surfacing these build scans in our GitHub Actions workflows.

We’ve now seen that urls for these build scans are logged at the end of our Gradle task execution. 

If running on a continuous integration (CI) server, this often means having to scroll, and parse, through hundreds or even thousands of lines of build output to find this url.  And that’s only useful if developers even know the url exists in the first place.

One way to help with this problem is to add these urls as comments on an open PR. In this section, we’re going to examine several variations of this idea. In each variant, we’re going to make use of the following GitHub Actions:

- [gradle-command-action](https://github.com/eskatos/gradle-command-action) – for executing Gradle tasks
- [add-pr-comment](https://github.com/mshick/add-pr-comment) – for commenting on an open pull request

These actions will do most of the heavy lifting for us.

### Adding a Single Job’s Gradle Build Scan URL as a Pull Request Comment

[Code Sample Here](https://github.com/n8ebel/GitHubActionsAutomationSandbox/blob/ne/buildscan-recipes/.github/workflows/single-job-buildscan-pr-comment.yml)

Let’s first imagine we have a GitHub Actions workflow running a single [job](https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#jobs). That job is configured to assemble our app.

We can use the _[gradle-command-action](https://github.com/eskatos/gradle-command-action)_ action to run our desired Gradle task.

```
- id: gradle uses: eskatos/gradle-command-action@v1 with: arguments: assembleDebug
```

This action will automatically parse our build output, find the build scan url, and add it as an output that can be accessed from other steps in the job.

```
steps.gradle.outputs.build-scan-url
```

Notice the structure of this output. `steps.gradle` is referencing the job build step with id `gradle`. Then, `outputs.build-scan-url` is referencing a specific output for that build step.

Now that we have access to the build scan url, we can use the _[add-pr-comment](https://github.com/mshick/add-pr-comment)_ action in add the url as a pull request comment.

```
- name: Add Build Scan URLs to Pull Request uses: mshick/add-pr-comment@v1 with: repo-token: ${{ secrets.GITHUB\_TOKEN }} message: Buildscan url ${{ steps.gradle.outputs.build-scan-url }}
```

We could go one step further, and customize the PR comment a bit more.

In this example, we’ll add the workflow run id for this specific build scan so we can more closely tie the url to the workflow.

```
- name: Add Build Scan URLs to Pull Request uses: mshick/add-pr-comment@v1 with: repo-token: ${{ secrets.GITHUB\_TOKEN }} message: | \*\*Buildscan url for run [${{ github.run\_id }}](https://github.com/n8ebel/GitHubActionsAutomationSandbox/actions/runs/${{ github.run\_id }})\*\* ${{ steps.gradle.outputs.build-scan-url }}
```

Once this workflow is run, we’ll now get PR comments for each successful run of our workflow.

<section><div></div>
<div>
<div><p><img data-attachment-id="4309" data-permalink="https://goobar.io/2020/10/13/surfacing-gradle-build-scans-within-github-actions/screen-shot-2020-10-10-at-7-09-16-am/" data-orig-file="https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-7.09.16-AM.png?fit=915%2C122&amp;ssl=1" data-orig-size="915,122" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="Screen-Shot-2020-10-10-at-7.09.16-AM" data-image-description="" data-medium-file="https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-7.09.16-AM.png?fit=300%2C40&amp;ssl=1" data-large-file="https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-7.09.16-AM.png?fit=800%2C107&amp;ssl=1" loading="lazy" width="800" height="107" src="https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-7.09.16-AM.png?resize=800%2C107&amp;ssl=1" alt="" srcset="https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-7.09.16-AM.png?w=915&amp;ssl=1 915w, https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-7.09.16-AM.png?resize=300%2C40&amp;ssl=1 300w, https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-7.09.16-AM.png?resize=768%2C102&amp;ssl=1 768w" sizes="(max-width: 800px) 100vw, 800px" data-recalc-dims="1"><figcaption>Example pull request comment including a Gradle build scan url</figcaption></p></div>
</div></section>
### Adding Build Scan URL Comments for Multiple Jobs

[Code Sample Here](https://github.com/n8ebel/GitHubActionsAutomationSandbox/blob/ne/buildscan-recipes/.github/workflows/multiple-job-multiple-buildscan-pr-comments.yml)

In many cases, our workflows will have more than one job. If we’re running Gradle tasks for each job, this will result in multiple build scans.

So how can we surface each build scan for the workflow?

The easiest approach, is to extend our previous example and add PR comments for each job.

```
jobs: test\_job: name: Test runs-on: ubuntu-latest steps: ... - id: gradle uses: eskatos/gradle-command-action@v1 with: arguments: test - name: Add Build Scan URL to Pull Request uses: mshick/add-pr-comment@v1 with: repo-token: ${{ secrets.GITHUB\_TOKEN }} message: | \*\*Test job buildscan url for run [${{ github.run\_id }}](https://github.com/n8ebel/GitHubActionsAutomationSandbox/actions/runs/${{ github.run\_id }})\*\* ${{ steps.gradle.outputs.build-scan-url }} assemble: name: Assemble Debug runs-on: ubuntu-latest steps: ... - id: gradle uses: eskatos/gradle-command-action@v1 with: arguments: assembleDebug - name: Add Build Scan URL to Pull Request uses: mshick/add-pr-comment@v1 with: repo-token: ${{ secrets.GITHUB\_TOKEN }} message: | \*\*Assemble job buildscan url for run [${{ github.run\_id }}](https://github.com/n8ebel/GitHubActionsAutomationSandbox/actions/runs/${{ github.run\_id }})\*\* ${{ steps.gradle.outputs.build-scan-url }}
```

Here, we’ve added a comment for each of the jobs run. In this case, we’ve customized the comment text to indicate which job the build scan is associated with; Test or Assemble.

The resulting PR looks something like this:

<section><div></div>
<div>
<div><p><img data-attachment-id="4317" data-permalink="https://goobar.io/2020/10/13/surfacing-gradle-build-scans-within-github-actions/untitled-design-5/" data-orig-file="https://i1.wp.com/goobar.io/wp-content/uploads/2020/10/Untitled-design.png?fit=600%2C200&amp;ssl=1" data-orig-size="600,200" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="Untitled-design" data-image-description="" data-medium-file="https://i1.wp.com/goobar.io/wp-content/uploads/2020/10/Untitled-design.png?fit=300%2C100&amp;ssl=1" data-large-file="https://i1.wp.com/goobar.io/wp-content/uploads/2020/10/Untitled-design.png?fit=600%2C200&amp;ssl=1" loading="lazy" width="600" height="200" src="https://i1.wp.com/goobar.io/wp-content/uploads/2020/10/Untitled-design.png?resize=600%2C200&amp;ssl=1" alt="" srcset="https://i1.wp.com/goobar.io/wp-content/uploads/2020/10/Untitled-design.png?w=600&amp;ssl=1 600w, https://i1.wp.com/goobar.io/wp-content/uploads/2020/10/Untitled-design.png?resize=300%2C100&amp;ssl=1 300w" sizes="(max-width: 600px) 100vw, 600px" data-recalc-dims="1"><figcaption>Multiple build scan PR comments; one for each job in the workflow</figcaption></p></div>
</div></section>

This approach succeeds in surfacing the build scan urls. However, it also results in a lot of PR noise as each workflow run may result in multiple PR comments.

### Consolidating Multiple Job’s Build Scan URLs Into a Single Pull Request Comment

[Code Sample Here](https://github.com/n8ebel/GitHubActionsAutomationSandbox/blob/ne/buildscan-recipes/.github/workflows/multiple-job-single-buildscan-pr-comment.yml)

To improve upon the previous example, we’ll consolidate all the build scan urls for a workflow into a single PR comment. That way, we’ll have a 1:1 mapping between a workflow run and build scan PR comments.

The general idea of this approach is this:

- Expose each build scan url as a job output
- Delay adding PR comments until all relevant jobs have completed
- Add a new job that waits for relevant jobs, and adds a single PR comment including all the build scan urls

```
jobs: test: name: Test runs-on: ubuntu-latest outputs: buildScanUrl: ${{ steps.gradle.outputs.build-scan-url }} steps: ... - id: gradle uses: eskatos/gradle-command-action@v1 with: arguments: test assemble: name: Assemble Debug runs-on: ubuntu-latest outputs: buildScanUrl: ${{ steps.gradle.outputs.build-scan-url }} steps: ... - id: gradle uses: eskatos/gradle-command-action@v1 with: arguments: assembleDebug notification\_job: needs: [test, assemble] name: Add Build Scan URLs runs-on: ubuntu-latest steps: - uses: mshick/add-pr-comment@v1 with: repo-token: ${{ secrets.GITHUB\_TOKEN }} message: | \*\*Build scans for run: [${{ github.run\_id }}](https://github.com/premisedata/mobile-android/actions/runs/${{ github.run\_id }})\*\* \* Test Build Scan ${{ needs.test.outputs.buildScanUrl }} \* Assemble Build Scan ${{ needs.assemble.outputs.buildScanUrl }}
```

With all build scan urls consolidated into a single comment, our PR output might look something like this:

<section><div></div>
<div>
<div><p><img data-attachment-id="4320" data-permalink="https://goobar.io/2020/10/13/surfacing-gradle-build-scans-within-github-actions/screen-shot-2020-10-10-at-7-56-39-am/" data-orig-file="https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-7.56.39-AM.png?fit=912%2C162&amp;ssl=1" data-orig-size="912,162" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="Screen-Shot-2020-10-10-at-7.56.39-AM" data-image-description="" data-medium-file="https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-7.56.39-AM.png?fit=300%2C53&amp;ssl=1" data-large-file="https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-7.56.39-AM.png?fit=800%2C142&amp;ssl=1" loading="lazy" width="800" height="142" src="https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-7.56.39-AM.png?resize=800%2C142&amp;ssl=1" alt="A single pull request comment that contains multiple Gradle build scan urls" srcset="https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-7.56.39-AM.png?w=912&amp;ssl=1 912w, https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-7.56.39-AM.png?resize=300%2C53&amp;ssl=1 300w, https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-7.56.39-AM.png?resize=768%2C136&amp;ssl=1 768w" sizes="(max-width: 800px) 100vw, 800px" data-recalc-dims="1"><figcaption>A single build scan PR comment for all jobs in the workflow</figcaption></p></div>
</div></section>

Now, we will see a single comment for each workflow run.

If any job fails for a workflow run, we can find the associated build scan url for that job, and start investigating the issue.

## Storing Gradle Build Scan URLs In GitHub Actions Workflow Artifacts

Surfacing build scan urls as PR comments might be a useful improvement to your pull request workflows.

However, not all workflows have an associated pull request. You may have a nightly build. Or a scheduled release build. Or any number of other automated workflows that don’t have an associated pull request.

If something goes wrong for those builds, we still want to quickly find the associated build scan and start diagnosing the problem.

How then can we improve discoverability of build scans for non-pull-request workflows?

One solution is to write the build scan urls to a file stored as a build artifact.

Within our GitHub Actions workflows, [we can store any number of different build artifacts](https://docs.github.com/en/free-pro-team@latest/actions/guides/storing-workflow-data-as-artifacts). These could be things like testing or linting reports, or maybe your .apk file.

Storing artifacts is quite straightforward using the _[upload-artifact](https://github.com/actions/upload-artifact)_ action.

```
- uses: actions/upload-artifact@v2 with: name: some-artifact path: path/to/artifact/some\_artifact.txt
```

This sample will store the file _some\_artifact.txt_ in a workflow artifact named _some-artifact_.

We will use this approach to save a set of files that contain build scan urls for workflows that don’t include a PR.

### Writing Gradle Build Scan URLs to a File

To write our build scan URL to a file, we can make use of the _buildScanPublished {}_ callback of the Gradle Enterprise plugin.

We see in this example that we’ve added the _buildScanPublished_ block, which is called with the current _PublishedBuildScan_ object, once the scan is published.

```
gradleEnterprise { buildScan { termsOfServiceUrl = "https://gradle.com/terms-of-service" termsOfServiceAgree = "yes" publishAlways() buildScanPublished { PublishedBuildScan scan -> file("buildscan.log") << "${new Date()} - ${scan.buildScanUri}\n" } } }
```

Once we have the scan, we can use it however we want.

In this case, we’re creating a new file named _buildscan.log_ and writing the build scan uri to the file, along with the current timestamp.

Locally, as multiple build scans are generated, this file will continue to populate that list.

On CI, where builds are run in a clean environment, this file will include only the most recent build scan.

### Storing Build Scan Files as Workflow Artifacts

[Code Sample Here](https://github.com/n8ebel/GitHubActionsAutomationSandbox/blob/ne/buildscan-recipes/.github/workflows/buildscan-as-file-artifact.yml)

Now that our builds will generate these build scan files, we need to store them as a workflow artifact so we can go back and view them for any arbitrary workflow.

For each job, we’ll add a build step that stores the _buildscan.log_ file as a build artifact.

```
jobs: test\_job: name: Test runs-on: ubuntu-latest steps: ... - name: Save Build Scan Log uses: actions/upload-artifact@v2 with: name: buildscan-test path: 'buildscan.log' assemble\_job: name: Assemble runs-on: ubuntu-latest steps: ... - name: Save Build Scan Log uses: actions/upload-artifact@v2 with: name: buildscan-assemble path: 'buildscan.log'
```

To avoid overwriting the artifact, each job writes the _buildscan.log_ file to a different artifact.

The result is something like this:

<section><div></div>
<div>
<div><p><img data-attachment-id="4324" data-permalink="https://goobar.io/2020/10/13/surfacing-gradle-build-scans-within-github-actions/screen-shot-2020-10-10-at-8-30-07-am/" data-orig-file="https://i1.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.30.07-AM.png?fit=1311%2C348&amp;ssl=1" data-orig-size="1311,348" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="Screen-Shot-2020-10-10-at-8.30.07-AM" data-image-description="" data-medium-file="https://i1.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.30.07-AM.png?fit=300%2C80&amp;ssl=1" data-large-file="https://i1.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.30.07-AM.png?fit=800%2C213&amp;ssl=1" loading="lazy" width="800" height="213" src="https://i1.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.30.07-AM.png?resize=800%2C213&amp;ssl=1" alt="Multiple GitHub Actions workflow artifacts that each contain a Gradle build scan url" srcset="https://i1.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.30.07-AM.png?resize=1024%2C272&amp;ssl=1 1024w, https://i1.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.30.07-AM.png?resize=300%2C80&amp;ssl=1 300w, https://i1.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.30.07-AM.png?resize=768%2C204&amp;ssl=1 768w, https://i1.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.30.07-AM.png?resize=1200%2C319&amp;ssl=1 1200w, https://i1.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.30.07-AM.png?resize=1140%2C303&amp;ssl=1 1140w, https://i1.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.30.07-AM.png?w=1311&amp;ssl=1 1311w" sizes="(max-width: 800px) 100vw, 800px" data-recalc-dims="1"><figcaption>Multiple workflow artifacts storing build scan files</figcaption></p></div>
</div></section>

This allows us to find the build scan urls for a non-PR workflow without browsing the build logs.

Unfortuneately, this approach requires us to download multiple artifacts to view all of the workflow’s build scan urls.

So for one final improvement, we’ll look at how to consolidate all the _buildscan.log_ files into a single file artifact.

### Storing Multiple Build Scan Files as a Single Workflow Artifact

[Code Sample Here](https://github.com/n8ebel/GitHubActionsAutomationSandbox/blob/ne/buildscan-recipes/.github/workflows/multiple-buildscans-as-single-file-artifact.yml)

To store our build scan files in a single artifact, we need to be able to customize the file name of the _buildscan.log_ files.

There’s probably many different ways to go about this, and I’ll cover just one here.

We’ll add an environment variable to the Gradle task build step. This variable will be used as a filename prefix for our _buildscan.log_ file.

```
jobs: test\_job: name: Test runs-on: ubuntu-latest steps: ... - id: gradle uses: eskatos/gradle-command-action@v1 env: BUILDSCAN\_FILE\_PREFIX: test with: arguments: test ... assemble\_job: name: Assemble runs-on: ubuntu-latest steps: ... - id: gradle uses: eskatos/gradle-command-action@v1 env: BUILDSCAN\_FILE\_PREFIX: assemble-debug with: arguments: assembleDebug ...
```

Now, we can update our _buildScanPublished{}_ configuration to use the prefix when naming the _buildscan.log_ file.

```
buildScanPublished { PublishedBuildScan scan -> def scanNamePrefix = System.getenv("BUILDSCAN\_FILE\_PREFIX") ? "${System.getenv("BUILDSCAN\_FILE\_PREFIX")}-" : "" def filename = scanNamePrefix + "buildscan.log" file(filename) << "${new Date()} - ${scan.buildScanUri}\n" }
```

Now, each job’s _buildscan.log_ file should have a unique name corresponding to the environment variable adding to the Gradle execution build step.

So our last step, is to update the workflow so that each job uploads the unique _buildscan.log_ files to the same artifact.

```
jobs: test\_job: name: Test runs-on: ubuntu-latest steps: ... - id: gradle uses: eskatos/gradle-command-action@v1 env: BUILDSCAN\_FILE\_PREFIX: test with: arguments: test - name: Save Build Scan Log if: ${{ always() }} uses: actions/upload-artifact@v2 with: name: buildscans path: 'test-buildscan.log' assemble\_job: name: Assemble runs-on: ubuntu-latest steps: ... - id: gradle uses: eskatos/gradle-command-action@v1 env: BUILDSCAN\_FILE\_PREFIX: assemble-debug with: arguments: assembleDebug - name: Save Build Scan Log if: ${{ always() }} uses: actions/upload-artifact@v2 with: name: buildscans path: 'assemble-debug-buildscan.log'
```

Now, when our workflow is completed, we’ll have a single artifact called _buildscans_.

<section><div></div>
<div>
<div><p><img data-attachment-id="4328" data-permalink="https://goobar.io/2020/10/13/surfacing-gradle-build-scans-within-github-actions/screen-shot-2020-10-10-at-8-47-10-am/" data-orig-file="https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.47.10-AM.png?fit=1307%2C309&amp;ssl=1" data-orig-size="1307,309" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="Screen-Shot-2020-10-10-at-8.47.10-AM" data-image-description="" data-medium-file="https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.47.10-AM.png?fit=300%2C71&amp;ssl=1" data-large-file="https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.47.10-AM.png?fit=800%2C189&amp;ssl=1" loading="lazy" width="800" height="189" src="https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.47.10-AM.png?resize=800%2C189&amp;ssl=1" alt="A single GitHub Actions workflow artifact that contains multiple build scan urls" srcset="https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.47.10-AM.png?resize=1024%2C242&amp;ssl=1 1024w, https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.47.10-AM.png?resize=300%2C71&amp;ssl=1 300w, https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.47.10-AM.png?resize=768%2C182&amp;ssl=1 768w, https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.47.10-AM.png?resize=1200%2C284&amp;ssl=1 1200w, https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.47.10-AM.png?resize=1140%2C270&amp;ssl=1 1140w, https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.47.10-AM.png?w=1307&amp;ssl=1 1307w" sizes="(max-width: 800px) 100vw, 800px" data-recalc-dims="1"><figcaption>A single workflow artifact for all build scan files</figcaption></p></div>
</div></section>

Once downloaded, we have access to each _buildscan.log_ file for the workflow.

<section><div></div>
<div>
<div><p><img data-attachment-id="4329" data-permalink="https://goobar.io/2020/10/13/surfacing-gradle-build-scans-within-github-actions/screen-shot-2020-10-10-at-8-47-45-am/" data-orig-file="https://i0.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.47.45-AM.png?fit=727%2C117&amp;ssl=1" data-orig-size="727,117" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="Screen-Shot-2020-10-10-at-8.47.45-AM" data-image-description="" data-medium-file="https://i0.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.47.45-AM.png?fit=300%2C48&amp;ssl=1" data-large-file="https://i0.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.47.45-AM.png?fit=727%2C117&amp;ssl=1" loading="lazy" width="727" height="117" src="https://i0.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.47.45-AM.png?resize=727%2C117&amp;ssl=1" alt="Build scan files stored within a GitHub Actions workflow artifact" srcset="https://i0.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.47.45-AM.png?w=727&amp;ssl=1 727w, https://i0.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.47.45-AM.png?resize=300%2C48&amp;ssl=1 300w" sizes="(max-width: 727px) 100vw, 727px" data-recalc-dims="1"><figcaption>The single workflow artifact will contain all the buildscan.log files once unzipped</figcaption></p></div>
</div></section>

Now, for any workflow that’s run, we can download the _buildscans_ artifact and immediately find the build scan urls for that workflow.

<section><div></div>
<div>
<h2>Learn More</h2>

<div><div>
<div><div><a href="https://goobar.io/tag/github-actions/" rel="noopener noreferrer" target="_blank"><div>More GitHub Actions</div></a></div></div>

<div><div><a href="#" rel="noopener noreferrer" target="_self"><div>Check Out The Docs </div></a></div></div>
</div></div>
</div></section>
## Wrapping Up

In this post, we’ve explored several different ways of making Gradle build scan urls easier to find within our GitHub Actions workflows.

The effectiveness of these approaches likely depends upon your team. If your team is using Gradle Enterprise and everyone is comfortable using that tool to find build scans, then surfacing them in workflows may not be that helpful.

However, if not everyone on your team is familiar with Gradle Enterprise, or you’re not using Gradle Enterprise, then surfacing the build scan urls in a more visible location may in fact help your team quite a bit.

* * *

The post [Surfacing Gradle Build Scans Within GitHub Actions Workflows](https://goobar.io/2020/10/13/surfacing-gradle-build-scans-within-github-actions/) appeared first on [goobar](https://goobar.io).