If an existing dependency graph file is present for the configured job correlator,
we now generate a unique correlator value for the invocation. This allows the action
to submit dependency snapshots for a series of Gradle invocations within the same Job.
This commit updates to `github-dependency-graph-gradle-plugin@v0.0.6`, which reduces
redundancy in the mapping of resolved Gradle dependencies to the GitHub Dependency Graph.
Adds a 'dependency-graph' parameter that has 4 options:
1. 'disabled': no dependency graph files generated (the default)
2. 'generate': dependency graph files will be generated and saved as artifacts.
3. 'generate-and-submit': dependency graph files will be generated, saved as artifacts,
and submitted to the Dependency Submission API on job completion.
4. 'download-and-submit': any previously uploaded dependency graph artifacts will be downloaded
and submitted to the Dependency Submission API.
Instead of requiring an action step to generate the graph, configure Gradle User Home
so that subsequent Gradle invocations can generate a graph. Any generated graph files
are uploaded as artifacts on job completion.
- Construct job.correlator from workflow/job/matrix
- Export job.correlator as an environment var
- Upload artifacts at job completion in post-action step
- Specify the location of dependency graph report
- Only apply dependency graph init script when explicitly enabled
Moved reading of all input parameters into a common source: `input-params.ts`.
This centralized all input parameter reads, and allowed an improved implementation
of reading boolean parameters. In particular, the implementation now provides a default
value for a boolean input parameter that isn't declared for an action.
Introducing new actions for the GitHub dependency graph will involve reuse of much of
the action infrastructure. This commit reorganises things a little to facilitate reuse.
The `PluginManager.hasPlugin` method was not detecting the GE plugin when it
was applied during settingsEvaluated.
Switching to `PluginManager.withPlugin` fixes this.
Fixes#626
With Gradle 8.1, the configuration-cache has changed and is now stable.
As a temporary measure, this commit disables save/restore of the configuration-cache
data to avoid issues until we can deal with this change properly.
When configuration-cache is enabled, the invocationId may not be unique, which can result in
mulitple builds writing to the same file. Rather than failing the post-action, we simply
ignore any subsequent build results with the same ID.
Fixes#441
Logging of the AZURE_LOG_LEVEL env var value is considered a security issue,
since any environment variable value could contain sensitive information.
In this case, logging the value is not really necessary.
The included sourcemap-register.js file is triggering a high priority
CodeQL warning, which can prevent users from adopting the action.
Removing this sourcemap support for now, until this can be fixed upstream.
- Bump eslint from 8.23.0 to 8.23.1
- Bump typescript from 4.8.2 to 4.8.3
- Bump eslint-plugin-jest from 27.0.1 to 27.0.4
- Bump @typescript-eslint/parser from 5.36.2 to 5.37.0
- Includes basic implementation as `CacheCleaner`
- Integration test that checks unused files are removed:
- Downloaded dependencies
- Local build cache entries
- Wrapper distributions
Now that `@actions/cache` provides a env var override, we can remove our
custom configuration for setting the timeout on cache restore operations.
If the env var is NOT set, we continue to override the 60min default with 10mins.
It appears that when restoring the Gradle User Home directory, certain empty
directories are being identified by Node as broken symlinks. This results in
`Error: ENOENT: No such file or directory` when attempting to resolve a Glob pattern.
By using the default behaviour of Globber (followSymbolicLinks && ignoreBrokenLinks),
these bad files no longer cause errors when saving the Gradle User Home to cache.
Fixes#408
The fix for #383 introduced a bug that caused the post-action to fail when
attemping to resolve `cache-read-only` for scheduled jobs.
This has been fixed with an explicit (rather than implicit) check for 'event.repository != null'.
Fixes#409
This commit reverts the change in v3.0.0 of @actions/cache, that
causes cache errors to be logged and swallowed. By allowing these
errors to propogate, the action can take appropriate action and
provide useful error messages.
Fixes#407
For scheduled workflows, we don't know the default branch. In this case cannot determine if
the workflow is running on the default branch, and so cannot know when to enable `cache-read-only`.
Fixes#383
The init-scripts added to Gradle User Home were assuming the presence of certain
GitHub Actions environment variables. With this fix, these init scripts behave
better without these env vars.
Fixes#350
Although convenient, the os.homedir() function can return a different value
that the 'user.home' SystemProperty in Java. The latter is used to locate
the Gradle User Home directory.
By switching to use Java to determine the value for 'user.home', we can use
the same process as Gradle to determine Gradle User Home.
Fixes#207
Now that we are stopping all Gradle daemons in the post-job action,
we can allow daemon processes to be re-used across steps in a workflow job.
Fixes#113
Improve init scripts and add test coverage
The build-scan-capture init script will now capture results from builds that do not publish a build-scan, with and without the configuration-cache.
Fixes#292
When enabled, the configuration-cache will cause the build to fail when a
`buildFinished` listener is added. Instead, use a BuildService to listen for task
failures and to write the results on build completion.
The `gradle-build-action` test workflows need to write cache entries,
even when run on non-default branches. This change add explicit configuration
to set `cache-read-only: false` when cache writing is required.
Cache entries _written_ from jobs run on a non-default branch will be private
to other jobs for that branch. When development flow involves working on a
feature branch and then merging into 'main', these branch-private cache
entries can result in eviction of other (shared) cache entries generated
for the default branch.
With this change, we make the recommended setup the default, by running
with `cache-read-only: true` for any jobs run on a non-default branch.
These jobs will be able to read cache entries written from the main branch,
but will not write any cache entries.
Fixes#143
- Bump typescript from 4.7.2 to 4.7.3
- Bump ts-jest from 28.0.3 to 28.0.4
- Added @types/jest which is now required
- Bump eslint from 8.16.0 to 8.17.0
Using `settingsEvaluated` meant that the project root was not recorded
when the build was run with a config-cache hit. This meant that the subsequent
build would not restore the config-cache, resulting in a cache miss.
In order to avoid issues running the init script on older versions of Gradle
the project-collection is extracted into a separate groovy file that is only
applied conditionally on Gradle 7 or higher.
Various improvements to CI workflows
- Compose all integ-test workflow executions into a single calling workflow
- Added a 'quick-check' workflow that provides faster feedback on branches other than main
- Only runs on ubuntu-latest
- Reuses cache entries from previous runs
- Builds distribution outputs so that these don't need to be committed during everyday development
- Added a workflow for purging old workflow executions
Together with the fix for #293, these changes fix#291
The action requires the generated distribution to committed to the 'dist' directory.
During regular development this step causes a number of problems:
- It's easy to forget to add/commit these generated files.
- It's very difficult/impossible to merge/rebase commits that involve generated files
- These file add unnecessary bulk to the git history
With this change, the quick-check workflow will first build the distribution and then
use the generated output for testing. Building and committing these files will only be
required when merging into the 'main' branch.
- Workflow to run all integTest workflows, allowing use of prior cache entries
- Workflow that starts with empty cache
Both of these use workflow_call to combine the existing workflows.
The wrapper zip files are redundant, and not required after extraction.
Gradle 7.5+ will delete these automatically, but we delete them for older
versions to avoid caching the wrapper distributions twice.
Sinc the `gradle-home-cache-excludes` parameter does not support
wildcards, we remove them explicitly.
- Bump @actions/cache from 2.0.4 to 2.0.5
- Bump ts-jest from 28.0.2 to 28.0.3
- Bump typescript from 4.6.4 to 4.7.2
- Bump @vercel/ncc from 0.33.4 to 0.34.0
Production deps:
- Bump @actions/tool-cache from 1.7.2 to 2.0.1
- Bump @actions/http-client from 1.0.11 to 2.0.1
- Bump @actions/github from 5.0.1 to 5.0.3
- Bump @actions/cache from 2.0.2 to 2.0.4
Dev deps:
- Bump eslint from 8.14.0 to 8.15.0
- Bump eslint-plugin-jest from 26.2.0 to 26.2.2
- Bump jest from 27.5.1 to 28.1.0
- Bump ts-jst from 27.1.4 to 28.0.2
- Remove explicit dependency on jest-circus: this is now the default runner
- Remove test timeout setting
- Remove @types/jest from explicit dependencies
Production deps:
- Bump @actions/core:1.6.0 to 1.8.2
Development deps:
- Bump typescript from 4.6.3 to 4.6.4
- Bump @typescript-eslint/parser from 5.20.0 to 5.23.0
- Bump eslint-plugin-jest from 26.1.4 to 26.2.0
- Switch from deprecated @zeit/ncc to @vercel/ncc
To save space, future versions of Gradle are likely to delete the downloaded distribution
after extracting it. See gradle/gradle#3605 and gradle/gradle#19495.
To cater for this we will now save/restore the extracted distribution rather than the
downloaded zip file.
The test Gradle sample apps reference plugins, and it's good to keep these
updated (particularly the GE plugin).
Minor changes to the build scripts were required to satisfy Dependabot.
Now that environment variable reads are auto-detected by Gradle 7.4,
we need a different mechanism to check that the configuration cache is
being used successfully.
MacOS runners are initialized with a Gradle User Home directory including
the `~/.gradle/notifications` directory. This was causing the action to skip
restoring the Gradle User Home on MacOS.
This fix limits the pre-existing GUH check to the `~/.gradle/caches` directory
which isn't pre-initialized in the runner.
Fixes#155
Improves logging for caching, and adds 2 experimental cache options:
- `gradle-home-cache-strict-match`: Avoid re-using a Gradle Home cache entry written by a different job. Only cache entries written by the current Job will be used.
- `cache-write-only`: Do not restore existing cache entries, but still save cache entries in post-action. Fixes#141.
There may be cases where it a "fresh" cache entry would be beneficial,
for example if the Gradle User Home cache entry grows over time.
This setting would run the build as if no prior cache entry exists.
By default, the action will attempt to restore a Gradle User Home
cache entry from a different set of matrix inputs (or a different Job entirely)
if an existing entry is not found for the current Job (including matrix inputs).
By specifying the experimental `gradle-home-cache-strict-match` parameter, a user
can avoid this fuzzy matching and ensure that a job execution starts with an
empty Gradle User Home if no entry from a prior execution is found.
Fix Build Scan capture when cache is disabled
With the change to use init-scripts to inject Build Scan capture, this functionality broke when caching was disabled and Gradle User Home wasn't initialized.
This PR fixes a couple of issues and ensures that the Gradle User Home is initialized even when it is not restored from the GitHub Actions cache.
Fixes#138Fixes#139
This change to the integration tests should properly isolate multiple runs of the same job.
Previously, some jobs would fail if you attempted to re-run them via the UI, because the cache
entries would be re-used from the previous run.
Instead of using a fallback strategy to locate a configuration-cache entry
based on the current job and git SHA, these entries are now keyed based on their
file content with the keys persisted in the primary Gradle User Home entry.
This removes the chance of having a configuration-cache entry restored that is
incompatible with the restored Gradle User Home state, and makes the logic easier
to understand.
This change involved a fairly major refactor, with the CacheEntryExtractor being
split out from the primary cache implementation, and adding a separate extractor
implementation for configuration-cache.
- Remove configuration parameter for cache-entry-definitions. This allows richer modelling of extracted entries.
- Include both *.zip and *.tar.gz in entry definition for java-toolchains.
If the user supplies no 'arguments' parameter, the action will function as a
'setup-gradle' action, adding Gradle to the PATH and enabling other features
without actually running a Gradle build.
Any subsequent Gradle invocations in the workflow will benefit from:
- Save/restore of Gradle User Home
- Save/restore of configuration-cache data
- Capture of build-scan URLs
These features are enabled via Gradle User Home, so any Gradle invocation that
uses the same Gradle User Home will be included.
Restore/save configuration-cache data in first action step. This will enable the use of the action for caching without managing all gradle invocations.
Previously, the action was restoring/saving the configuration-cache data for each
step that applied the action. In order to support Gradle invocations that are _not_
managed by the action, the configuration-cache restore is now performed in the initial
action step, and save is performed in the final post-action step.
The build root directories are recorded for each invocation via an init script.
Instead of relying on the separate cache implementations to check for the
existence of cached products, we now explicitly track whether or not the execution
is the first time the action has been invoked for a job.
Using a single cache entry for all files of a type is necessary to avoid
overloading the cache service. However, this mechanism is not very efficient
for certain artifacts like wrapper zips and generated-gradle-jars, where the
same individual files are often shared between different jobs.
With this change, any configured file patterns that do not end in '*' will
be cached as individual files. At this time this includes downloaded wrapper
zips and generated-gradle-jars.
Fixes#78
This is a pure refactor, moving from a separate .cache file per bundle to a single cache-metadata.json file describing all bundles. Instead of storing cache metadata in a separate .cache file per artifact bundle, all of the metadata is now stored in a single `.json` file.
This will make it easier to implement more flexible artifact-caching strategies, such as caching each wrapper zip separately.
* Always include cache protocol version in cache key
* Store all cache metadata in a single JSON file
* Rename cache-metadata file and bump protocol version
* Polish and documentation
Instead of writing the URL to a file on disk, reading it later and
using the Actions API to record the output parameter and write the notice,
these things are now done directly via Actions commands emitted directly
from the init script.
Instead of writing this file to a temp directory and referencing it
on the Gradle command line, the init script is now written to Gradle
User Home so that it is picked up automatically.
Instead of passing `--no-daemon` on the command line, the same
functionality is now acheived by writing a gradle.properties file
when initializing Gradle User Home.
Failures to store cache entries should not fail the action or the Job.
This fix attempts to catch and log any unexpected errors that occur when
saving cache entries.
Fixes: #119Fixes: #120
- Warn and continue on failure to restore a Gradle distribution from cache
- Warn and continue on failure to save a Gradle distribution to cache
- Extract common functionality for consistent handling of cache failures
Fixes#116
There's no easy way to get the size of restored/saved cache entries
using the @actions/cache library. Rather than reimplement it, this commit
adds a patch that will be applied whenever 'npm install' is run.
The work is done by 'patch-package'.
Fix issues for 2.0-rc.2
- Support multi-line strings for cache-tuning parameters #106
- Include all downloaded files in `dependencies` bundle #100
- Only restore configuration-cache if Gradle User Home is fully restored #107
Instead of tracking a single 'fully-restored' flag, track the restore status of each
cache entry restore. If any of these are requested but not restored, then the overall
Gradle User Home cache is not fully restored.
Added special handling for the case when zero artifact bundles are set: this is used
in tests to simulate a not-fully-restored state.
Previously, only .jar files were bundled, with other files (modules, POMs, zips, etc)
being left in Gradle User Home. All downloaded files are now included in the bundle.
Fixes#100
The `gradle-home-cache-includes` and `gradle-home-cache-excludes` parameters were initially implemented
as JSON string inputs. This makes these inputs non-idiomatic and easier to get wrong.
This change converts them to multi-line input parameters.
Fixes#106
Add some internal options for fine-tuning the gradle-build-action cache
- Can specify cache-paths to override the default directories cached from Gradle User Home
- Can specify cache-exclude-paths to exclude files from the Gradle User Home cache
- Files under caches/<gradle-version>/kotlin-dsl are now cached as a bundle
Ensure all-or-nothing restore of cached instrumented-jars
Leaving the .lock and .receipt files lying around was causing issues when the actual jar files were not restored. Now the entire directory will either be missing, or completely restored.
Fixes#91
Leaving the `.lock` and `.receipt` files lying around was causing
issues when the actual jar files were not restored. Now the entire
directory will either be missing, or completely restored.
Instead of parsing the log output, we instead register a
buildScanPublished listener and record the build scan URL
to a file. This file is subsequently read to report the
build scan URL.
Fixes#30
When caching is too fine-grained, an excessive number of cache
requests can result in HTTP 429 errors due to rate limiting.
By caching all artifacts of a particular type in a single entry
we hope to mitigate this, at the expense of some reduction in
cache space optimization.
This change also adds caching for all dependency jars, as well as
instrumented jars in the 'caches/jars-X' directory.
Unfortunately, doing this overloads the GitHub actions cache infrastructure
leading to failures and unpredictable results.
A later solution may re-implement artifact sharing for dependency jars
as well as jars within the `caches/jars-9` directory. But for now these
will be duplicated across each Gradle User Home cache entry.
Similar to wrapper distributions, these large files are common
to many Gradle User Home cache entries. Storing them separately removes
this redundancy from the Gradle User Home cache.
In the current model, each cached Gradle User Home could contain
a copy of one or more downloaded wrapper distributions. This results
in large cache entries which could easily lead to premature eviction.
With this change, wrapper dists are cached separately from the rest
of the Gradle User Home directory. The artifact file is replaced by
a marker file which allows the action to restore the artifact from
cache when the Gradle user Home cache is restored.
Attempt to capture as much context as possible about the job run
to generate a unique cache key. Unfortunately much of the matrix context
is not available to the action implementation.
This will eliminate cache entries from previous workflow runs, allowing
us to test cache functionality in isolation. If the `CACHE_KEY_SEED` environment
variable is not set, this will have no impact.
The Gradle daemon is not useful for ephemeral builds, and the process
can hold file locks which interfere with cache entry generation.
In the case where multiple Gradle invocations occur in the same job,
we could provide a way for users to override this behaviour, taking care
of stopping any daemon process at the end of the job.
- Do not restore cache when GUH exists
- Include RUNNER_OS in the cache key
- Do not save cache on exact hit
- Only save cache in the final post action
- Log before saving cache
Cache keys have a hard limit of 512 characters, so we need to ensure that we don't generate a key longer than this.
- Remove excess whitespace
- Truncate to 400 characters
Fixes#70
This makes the version alias match other places where we reference a release candidate version.
The 'rc' alias is still supported, but emits a deprecation warning.
- Cache is separate from (but similar to) the wrapper distribution cache
- New 'distributions-cache-enabled' flag controls caching of all downloaded distributions
(including wrapper distributions)
- Deprecated the 'wrapper-cache-enabled' flag for removal in v2
Prior to this change, the wrapper cache contained both the downloaded zip
file as well as the exploded wrapper dir. Only the zip file is required,
as Gradle will automatically detect and unpack.
- Provide a more useful error message when no Gradle wrapper can be located,
and 'gradle-version' or 'gradle-executable' is not used.
- Add test for case where wrapper is missing.
This isn't really a "test" per-se, but this failing build invocation makes it
easy to verify the GitHub action behaviour when the build is misconfigured.
- Remove the 'gradle --stop' step from the prod workflow.
We either need to stop all instances started, or rely on GitHub to clean up processes on completion.
- Remove configuration-cache and dependencies-cache from basic tests. We will later need to add
tests invocations specific for these features.
This is relevant if you run this action several times in a single job.
This prevent doing unnecessary work starting with the second job using the action.
This prevent droping dependencies downloaded by the first job using the action.
This prevent Windows agents to fail unlinking already existing files.
# This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging.
# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement
# Execute Gradle commands in GitHub Actions workflows
# Execute Gradle builds in GitHub Actions workflows
This GitHub Action can be used to run arbitrary Gradle commands on any platform supported by GitHub Actions.
This GitHub Action can be used to configure Gradle and optionally execute a Gradle build on any platform supported by GitHub Actions.
You might also be interested by the related [Gradle Plugin](https://github.com/eskatos/gradle-github-actions-plugin) that allows your build to easily get GitHub Actions environment and tag Gradle Build Scans accordingly.
## Usage
The following workflow will run `./gradlew build` using the wrapper from the repository on ubuntu, macos and windows. The only prerequisite is to have Java installed, you can define the version you need to run the build using the `actions/setup-java` action.
## Use the action to setup Gradle
If you have an existing workflow invoking Gradle, you can add an initial "Setup Gradle" Step to benefit from caching,
build-scan capture and other features of the gradle-build-action.
All subsequent Gradle invocations will benefit from this initial setup, via `init` scripts added to the Gradle User Home.
```yaml
# .github/workflows/gradle-build-pr.yml
name:Run Gradle on PRs
on:pull_request
jobs:
@@ -21,87 +19,61 @@ jobs:
os:[ubuntu-latest, macos-latest, windows-latest]
runs-on:${{ matrix.os }}
steps:
- uses:actions/checkout@v1
- uses:actions/setup-java@v1
- uses:actions/checkout@v3
- uses:actions/setup-java@v3
with:
distribution:temurin
java-version:11
- uses:eskatos/gradle-command-action@v1
with:
arguments:build
- name:Setup Gradle
uses:gradle/gradle-build-action@v2
- name:Execute Gradle build
run:./gradlew build
```
## Gradle arguments
## Why use the `gradle-build-action`?
The `arguments` input can used to pass arbitrary arguments to the `gradle` command line.
It is possible to directly invoke Gradle in your workflow, and the `actions/setup-java@v3` action provides a simple way to cache Gradle dependencies.
Here are some valid examples:
```yaml
arguments:build
arguments:check --scan
arguments:some arbitrary tasks
arguments:build -PgradleProperty=foo
arguments:build -DsystemProperty=bar
....
```
However, the `gradle-build-action` offers a number of advantages over this approach:
See `gradle --help` for more information.
- Easily [run the build with different versions of Gradle](#use-a-specific-gradle-version) using the `gradle-version` parameter. Gradle distributions are automatically downloaded and cached.
- More sophisticated and more efficient caching of Gradle User Home between invocations, compared to `setup-java` and most custom configurations using `actions/cache`. [More details below](#caching).
- Detailed reporting of cache usage and cache configuration options allow you to [optimize the use of the GitHub actions cache](#optimizing-cache-effectiveness).
- [Automatic capture of build scan links](#build-scans) from the build, making these easier to locate for workflow run.
If you need to pass environment variables, simply use the GitHub Actions workflow syntax:
The `gradle-build-action` is designed to provide these benefits with minimal configuration.
These features work both when Gradle is executed via the `gradle-build-action` and for any Gradle execution in subsequent steps.
When using `gradle-build-action` we recommend that you _not_ use `actions/cache` or `actions/setup-java@v3` to explicitly cache the Gradle User Home. Doing so may interfere with the caching provided by this action.
## Use a specific Gradle version
The `gradle-build-action` can download and install a specified Gradle version, adding this installed version to the PATH.
Downloaded Gradle versions are stored in the GitHub Actions cache, to avoid requiring downloading again later.
```yaml
- uses:eskatos/gradle-command-action@v1
env:
CI:true
```
## Run a build from a different directory
```yaml
- uses:eskatos/gradle-command-action@v1
with:
build-root-directory:some/subdirectory
```
## Use a Gradle wrapper from a different directory
```yaml
- uses:eskatos/gradle-command-action@v1
- uses:gradle/gradle-build-action@v2
with:
wrapper-directory:path/to/wrapper-directory
```
## Use a specific `gradle` executable
```yaml
- uses:eskatos/gradle-command-action@v1
with:
gradle-executable:path/to/gradle
gradle-version:6.5
```
## Setup and use a declared Gradle version
```yaml
- uses:eskatos/gradle-command-action@v1
with:
gradle-version:5.6.2
```
`gradle-version` can be set to any valid Gradle version.
The `gradle-version` parameter can be set to any valid Gradle version.
Moreover, you can use the following aliases:
| Alias | Selects |
| --- |---|
| `wrapper` | The Gradle wrapper's version (default, useful for matrix builds) |
| `current` | The current [stable release](https://gradle.org/install/) |
| `rc` | The current [release candidate](https://gradle.org/release-candidate/) if any, otherwise fallback to `current` |
| `nightly` | The latest [nightly](https://gradle.org/nightly/), fails if none. |
| `release-nightly` | The latest [release nightly](https://gradle.org/release-nightly/), fails if none. |
| `wrapper`| The Gradle wrapper's version (default, useful for matrix builds) |
| `current`| The current [stable release](https://gradle.org/install/) |
| `release-candidate` | The current [release candidate](https://gradle.org/release-candidate/) if any, otherwise fallback to `current` |
| `nightly` | The latest [nightly](https://gradle.org/nightly/), fails if none. |
| `release-nightly` | The latest [release nightly](https://gradle.org/release-nightly/), fails if none. |
This can be handy to, for example, automatically test your build with the next Gradle version once a release candidate is out:
This can be handy to automatically verify your build works with the latest release candidate of Gradle:
```yaml
# .github/workflows/test-gradle-rc.yml
name:Test latest Gradle RC
on:
schedule:
@@ -110,26 +82,24 @@ jobs:
gradle-rc:
runs-on:ubuntu-latest
steps:
- uses:actions/checkout@v1
- uses:actions/setup-java@v1
- uses:actions/checkout@v3
- uses:actions/setup-java@v3
with:
distribution:temurin
java-version:11
- uses:eskatos/gradle-command-action@v1
- uses:gradle/gradle-build-action@v2
with:
gradle-version:rc
arguments:build --dry-run# just test build configuration
gradle-version:release-candidate
- run:gradle build --dry-run# just test build configuration
```
# Build scans
## Gradle Execution
If your build publishes a [build scan](https://gradle.com/build-scans/) the `gradle-command-action` action will emit the link to the published build scan as an output named `build-scan-url`.
If the action is configured with an `arguments` input, then Gradle will execute a Gradle build with the arguments provided.
You can then use that link in subsequent actions of your workflow.
For example:
If no `arguments` are provided, the action will not execute Gradle, but will still cache Gradle state and configure build-scan capture for all subsequent Gradle executions.
It is possible to configure multiple Gradle executions to run sequentially in the same job.
The initial Action step will perform the Gradle setup.
```yaml
- uses:gradle/gradle-build-action@v2
with:
arguments:assemble
- uses:gradle/gradle-build-action@v2
with:
arguments:check
```
### Gradle command-line arguments
The `arguments` input can be used to pass arbitrary arguments to the `gradle` command line.
Arguments can be supplied in a single line, or as a multi-line input.
Here are some valid examples:
```yaml
arguments:build
arguments:check --scan
arguments:some arbitrary tasks
arguments:build -PgradleProperty=foo
arguments:|
build
--scan
-PgradleProperty=foo
-DsystemProperty=bar
```
If you need to pass environment variables, use the GitHub Actions workflow syntax:
```yaml
- uses:gradle/gradle-build-action@v2
env:
CI:true
with:
arguments:build
```
### Gradle build located in a subdirectory
By default, the action will execute Gradle in the root directory of your project.
Use the `build-root-directory` input to target a Gradle build in a subdirectory.
```yaml
- uses:gradle/gradle-build-action@v2
with:
arguments:build
build-root-directory:some/subdirectory
```
### Using a specific Gradle executable
The action will first look for a Gradle wrapper script in the root directory of your project.
If not found, `gradle` will be executed from the PATH.
Use the `gradle-executable` input to execute using a specific Gradle installation.
```yaml
- uses:gradle/gradle-build-action@v2
with:
arguments:build
gradle-executable:/path/to/installed/gradle
```
This mechanism can also be used to target a Gradle wrapper script that is located in a non-default location.
## Caching
By default, this action aims to cache any and all reusable state that may be speed up a subsequent build invocation.
The state that is cached includes:
- Any distributions downloaded to satisfy a `gradle-version` parameter ;
- A subset of the Gradle User Home directory, including downloaded dependencies, wrapper distributions, and the local build cache ;
To reduce the space required for caching, this action makes a best effort to reduce duplication in cache entries.
Caching is enabled by default. You can disable caching for the action as follows:
```yaml
cache-disabled:true
```
### Cache keys
Distributions downloaded to satisfy a `gradle-version` parameter are stored outside of Gradle User Home and cached separately. The cache key is unique to the downloaded distribution and will not change over time.
The state of the Gradle User Home is highly dependent on the Gradle execution, so the cache key is composed of the current commit hash and the GitHub actions job id.
As such, the cache key is likely to change on each subsequent run of GitHub actions.
This allows the most recent state to always be available in the GitHub actions cache.
To reduce duplication between cache entries, certain artifacts are cached independently based on their identity.
Artifacts that are cached independently include downloaded dependencies, downloaded wrapper distributions and generated Gradle API jars.
For example, this means that all jobs executing a particular version of the Gradle wrapper will share common entries for wrapper distributions and for generated Gradle API jars.
### Using the caches read-only
By default, the `gradle-build-action` will only write to the cache from Jobs on the default (`main`/`master`) branch.
Jobs on other branches will read entries from the cache but will not write updated entries.
See [Optimizing cache effectiveness](#optimizing-cache-effectiveness) for a more detailed explanation.
In some circumstances it makes sense to change this default, and to configure a workflow Job to read existing cache entries but not to write changes back.
You can configure read-only caching for the `gradle-build-action` as follows:
```yaml
# Only write to the cache for builds on the 'main' and 'release' branches. (Default is 'main' only.)
# Builds on other branches will only read existing entries from the cache.
By default, the action will stop all running Gradle daemons in the post-action step, prior to saving the Gradle User Home state.
This allows for any Gradle User Home cleanup to occur, and avoid file-locking issues on Windows.
If caching is unavailable or the cache is in read-only mode, the daemon will not be stopped and will continue running after the job is completed.
### Gradle User Home cache tuning
As well as any wrapper distributions, the action will attempt to save and restore the `caches` and `notifications` directories from Gradle User Home.
The contents to be cached can be fine tuned by including and excluding certain paths with Gradle User Home.
```yaml
# Cache downloaded JDKs in addition to the default directories.
gradle-home-cache-includes:|
caches
notifications
jdks
# Exclude the local build-cache and keyrings from the directories cached.
gradle-home-cache-excludes:|
caches/build-cache-1
caches/keyrings
```
You can specify any number of fixed paths or patterns to include or exclude.
File pattern support is documented at https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#patterns-to-match-file-paths.
### Cache debugging and analysis
Gradle User Home state will be restored from the cache during the first `gradle-build-action` step for any workflow job.
This state will be saved back to the cache at the end of the job, after all Gradle executions have completed.
A report of all cache entries restored and saved is printed to the Job Summary when saving the cache entries.
This report can provide valuable insignt into how much cache space is being used.
It is possible to enable additional debug logging for cache operations. You do via the `GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED` environment variable:
```yaml
env:
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED:true
```
Note that this setting will also prevent certain cache operations from running in parallel, further assisting with debugging.
### Optimizing cache effectiveness
Cache storage space for GitHub actions is limited, and writing new cache entries can trigger the deletion of existing entries.
Eviction of shared cache entries can reduce cache effectiveness, slowing down your `gradle-build-action` steps.
There are a number of actions you can take if your cache use is less effective due to entry eviction.
#### Select branches that should write to the cache
GitHub cache entries are not shared between builds on different branches.
This means that each PR branch will have it's own Gradle User Home cache, and will not benefit from cache entries written by other PR branches.
An exception to this is that cache entries written in parent and upstream branches are visible to child branches, and cache entries for the default (`master`/`main`) branch can be read by actions invoked for any other branch.
By default, the `gradle-build-action` will only _write_ to the cache for builds run on the default (`master`/`main`) branch.
Jobs run on other branches will only read from the cache. In most cases, this is the desired behaviour,
because Jobs run against other branches will benefit from the cache Gradle User Home from `main`,
without writing private cache entries that could lead to evicting shared entries.
If you have other long-lived development branches that would benefit from writing to the cache,
you can configure these by overriding the `cache-read-only` action parameter.
See [Using the caches read-only](#using-the-caches-read-only) for more details.
Similarly, you could use `cache-read-only` for certain jobs in the workflow, and instead have these jobs reuse the cache content from upstream jobs.
#### Exclude content from Gradle User Home cache
Each build is different, and some builds produce more Gradle User Home content than others.
[Cache debugging ](#cache-debugging-and-analysis) can provide insight into which cache entries are the largest,
and you can selectively [exclude content using `gradle-home-cache-exclude`](#gradle-user-home-cache-tuning).
#### Removing unused files from Gradle User Home before saving to cache
The Gradle User Home directory has a tendency to grow over time. When you switch to a new Gradle wrapper version or upgrade a dependency version
the old files are not automatically and immediately removed. While this can make sense in a local environment, in a GitHub Actions environment
it can lead to ever-larger Gradle User Home cache entries being saved and restored.
In order to avoid this situation, the `gradle-build-action` supports the `gradle-home-cache-cleanup` parameter.
When enabled, this feature will attempt to delete any files in the Gradle User Home that were not used by Gradle during the GitHub Actions workflow,
prior to saving the Gradle User Home to the GitHub Actions cache.
Gradle Home cache cleanup is disabled by default. You can enable this feature for the action as follows:
```yaml
gradle-home-cache-cleanup:true
```
## Build reporting
The `gradle-build-action` collects information about any Gradle executions that occur in a workflow, and reports these via
a Job Summary, visible in the GitHub Actions UI. For each Gradle execution, details about the invocation are listed, together with
a link to any Build Scan® published.
Generation of a Job Summary is enabled by default. If this is not desired, it can be disable as follows:
```yaml
generate-job-summary:false
```
Note that the action collects information about Gradle invocations via an [Initialization Script](https://docs.gradle.org/current/userguide/init_scripts.html#sec:using_an_init_script)
located at `USER_HOME/.gradle/init.d/build-result-capture.init.gradle`.
If you are using init scripts for the [Gradle Enterprise Gradle Plugin](https://plugins.gradle.org/plugin/com.gradle.enterprise) like
[`scans-init.gradle` or `gradle-enterprise-init.gradle`](https://docs.gradle.com/enterprise/gradle-plugin/#scans_gradle_com),
you'll need to ensure these files are applied prior to `build-result-capture.init.gradle`.
Since Gradle applies init scripts in alphabetical order, one way to ensure this is via file naming.
### Build scan link as Step output
As well as reporting the [Build Scan](https://gradle.com/build-scans/) link in the Job Summary,
the `gradle-build-action` action makes this link available as a Step output named `build-scan-url`.
You can then use that link in subsequent actions of your workflow. For example:
By default, a GitHub Actions workflow using `gradle-build-action` will record the log output and any Build Scan links for your build,
but any output files generated by the build will not be saved.
To save selected files from your build execution, you can use the core [Upload-Artifact](https://github.com/actions/upload-artifact) action.
For example:
```yaml
jobs:
gradle:
runs-on:ubuntu-latest
steps:
- name:Checkout project sources
uses:actions/checkout@v3
- name:Setup Gradle
uses:gradle/gradle-build-action@v2
- name:Run build with Gradle wrapper
run:./gradlew build --scan
- name:Upload build reports
uses:actions/upload-artifact@v3
with:
name:build-reports
path:build/reports/
```
## Support for GitHub Enterprise Server (GHES)
You can use the `gradle-build-action` on GitHub Enterprise Server, and benefit from the improved integration with Gradle. Depending on the version of GHES you are running, certain features may be limited:
- Build scan links are captured and displayed in the GitHub Actions UI
- Easily run your build with different versions of Gradle
- Save/restore of Gradle User Home (requires GHES v3.5+ : GitHub Actions cache was introduced in GHES 3.5)
- Support for GitHub Actions Job Summary (requires GHES 3.6+ : GitHub Actions Job Summary support was introduced in GHES 3.6). In earlier versions of GHES the build-results summary and caching report will be written to the workflow log, as part of the post-action step.
# GitHub Dependency Graph support
**EXPERIMENTAL**
The `gradle-build-action` has experimental support for submitting a [GitHub Dependency Graph](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-the-dependency-graph) snapshot via the [GitHub Dependency Submission API](https://docs.github.com/en/rest/dependency-graph/dependency-submission?apiVersion=2022-11-28).
The dependency graph snapshot is generated via integration with the [GitHub Dependency Graph Gradle Plugin](https://plugins.gradle.org/plugin/org.gradle.github-dependency-graph-gradle-plugin), and saved as a workflow artifact. The generated snapshot files can be submitted either in the same job, or in a subsequent job (in the same or a dependent workflow).
The generated dependency graph snapshot reports all of the dependencies that were resolved during a bulid execution, and is used by GitHub to generate [Dependabot Alerts](https://docs.github.com/en/code-security/dependabot/dependabot-alerts/about-dependabot-alerts) for vulnerable dependencies, as well as to populate the [Dependency Graph insights view](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/exploring-the-dependencies-of-a-repository#viewing-the-dependency-graph).
You enable GitHub Dependency Graph support by setting the `dependency-graph` action parameter. Valid values are:
| `disabled` | Do not generate a dependency graph for any build invocations.<p>This is the default. |
| `generate` | Generate a dependency graph snapshot for each build invocation, saving as a workflow artifact. |
| `generate-and-submit` | As per `generate`, but any generated dependency graph snapshots will be submitted at the end of the job. |
| `download-and-submit` | Download any previously saved dependency graph snapshots, submitting them via the Dependency Submission API. This can be useful to collect all snapshots in a matrix of builds and submit them in one step. |
- 'disabled': Do not generate a dependency graph for any build invocations. This is the default.
- 'generate': Generate a dependency graph snapshot for each build invocation, saving as a workflow artifact.
- 'generate-and-submit': As per 'generate', but any generated dependency graph snapshots will be submitted at the end of the job.
- 'download-and-submit': Download any previously saved dependency graph snapshots, submitting them via the Dependency Submission API. This can be useful to collect all snapshots in a matrix of builds and submit them in one step.
Dependency Graph _submission_ (but not generation) requires the `contents: write` permission, which may need to be explicitly enabled in the workflow file.
Example of a simple workflow that generates and submits a dependency graph:
```yaml
name:Submit dependency graph
on:
push:
permissions:
contents:write
jobs:
build:
runs-on:ubuntu-latest
steps:
- uses:actions/checkout@v3
- name:Setup Gradle to generate and submit dependency graphs
uses:gradle/gradle-build-action@dependency-graph
with:
dependency-graph:generate-and-submit
- name:Run a build, generating the dependency graph snapshot which will be submitted
run:./gradlew build
```
### Dependency snapshots generated for pull requests
This `contents: write` permission is not available for any workflow that is triggered by a pull request submitted from a forked repository, since it would permit a malicious pull request to make repository changes.
Because of this restriction, it is not possible to `generate-and-submit` a dependency graph generated for a pull-request that comes from a repository fork. In order to do so, 2 workflows will be required:
1. The first workflow runs directly against the pull request sources and will generate the dependency graph snapshot.
2. The second workflow is triggered on `workflow_run` of the first workflow, and will submit the previously saved dependency snapshots.
Note: when `download-and-submit` is used in a workflow triggered via [workflow_run](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run), the action will download snapshots saved in the triggering workflow.
***Main workflow file***
```yaml
name:run-build-and-generate-dependency-snapshot
jobs:
build:
runs-on:ubuntu-latest
steps:
- uses:actions/checkout@v3
- name:Setup Gradle to generate and submit dependency graphs
uses:gradle/gradle-build-action@v2
with:
dependency-graph:generate# Only generate in this job
- name:Run a build, generating the dependency graph snapshot which will be submitted
When 'true', entries will not be restored from the cache but will be saved at the end of the Job.
Setting this to 'true' implies cache-read-only will be 'false'.
required:false
default:false
gradle-home-cache-includes:
description:Paths within Gradle User Home to cache.
required:false
default:|
caches
notifications
gradle-home-cache-excludes:
description:Paths within Gradle User Home to exclude from cache.
required:false
# e.g. Use the following setting to prevent the local build cache from being saved/restored
# gradle-home-cache-excludes: |
# caches/build-cache-1
arguments:
description:Gradle command line arguments, see gradle --help
description:Gradle command line arguments (supports multi-line input)
required:false
generate-job-summary:
description:When 'false', no Job Summary will be generated for the Job.
required:false
default:true
dependency-graph:
description:Specifies if a GitHub dependency snapshot should be generated for each Gradle build, and if so, how. Valid values are 'disabled' (default), 'generate', 'generate-and-submit' and 'download-and-submit'.
required:false
default:'disabled'
# EXPERIMENTAL & INTERNAL ACTION INPUTS
# The following action properties allow fine-grained tweaking of the action caching behaviour.
# These properties are experimental and not (yet) designed for production use, and may change without notice in a subsequent release of `gradle-build-action`.
# Use at your own risk!
gradle-home-cache-strict-match:
description:When 'true', the action will not attempt to restore the Gradle User Home entries from other Jobs.
required:false
default:false
workflow-job-context:
description:Used to uniquely identify the current job invocation. Defaults to the matrix values for this job; this should not be overridden by users (INTERNAL).
required:false
default:${{ toJSON(matrix) }}
gradle-home-cache-cleanup:
description:When 'true', the action will attempt to remove any stale/unused entries from the Gradle User Home prior to saving to the GitHub Actions cache.
required:false
default:false
github-token:
description:The GitHub token used to authenticate when submitting via the Dependency Submission API.
- console.error(`AZURE_LOG_LEVEL set to unknown log level '${logLevelFromEnv}'; logging is not enabled. Acceptable values: ${AZURE_LOG_LEVELS.join(", ")}.`);
+ console.error(`AZURE_LOG_LEVEL set to unknown log level; logging is not enabled. Acceptable values: ${AZURE_LOG_LEVELS.join(", ")}.`);
- console.error(`AZURE_LOG_LEVEL set to unknown log level '${logLevelFromEnv}'; logging is not enabled. Acceptable values: ${AZURE_LOG_LEVELS.join(", ")}.`);
+ console.error(`AZURE_LOG_LEVEL set to unknown log level; logging is not enabled. Acceptable values: ${AZURE_LOG_LEVELS.join(", ")}.`);
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.