Skip to content

Commit

Permalink
Redirect some README content
Browse files Browse the repository at this point in the history
  • Loading branch information
bigdaz committed Jan 29, 2024
1 parent ef85c4e commit 4587492
Showing 1 changed file with 7 additions and 340 deletions.
347 changes: 7 additions & 340 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -479,348 +479,15 @@ You can use the `gradle-build-action` on GitHub Enterprise Server, and benefit f

# GitHub Dependency Graph support

The `gradle-build-action` has 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 build 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).

## Enable Dependency Graph generation for a workflow

You enable GitHub Dependency Graph support by setting the `dependency-graph` action parameter. Valid values are:

| Option | Behaviour |
| --- | --- |
| `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. |
| `generate-and-submit` | Generate a dependency graph snapshot for each build invocation, and submit these via the Dependency Submission API on completion of the job. |
| `generate-and-upload` | Generate a dependency graph snapshot for each build invocation, saving as a workflow artifact. |
| `download-and-submit` | Download any previously saved dependency graph snapshots, and submit them via the Dependency Submission API. This can be useful to submit [dependency graphs for pull requests submitted from a repository forks](#dependency-graphs-for-pull-request-workflows). |

Example of a CI workflow that generates and submits a dependency graph:
```yaml
name: CI build
on:
push:
permissions:
contents: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Gradle to generate and submit dependency graphs
uses: gradle/gradle-build-action@v2
with:
dependency-graph: generate-and-submit
- name: Run the usual CI build (dependency-graph will be generated and submitted post-job)
run: ./gradlew build
```

The `contents: write` permission is required in order to submit (but not generate) the dependency graph file.
Depending on [repository settings](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token), this permission may be available by default or may need to be explicitly enabled in the workflow file (as above).

> [!IMPORTANT]
> The above configuration will work for workflows that run as a result of commits to a repository branch,
> but not when a workflow is triggered by a PR from a repository fork.
> This is because the `contents: write` permission is not available when executing a workflow
> for a PR submitted from a forked repository.
> For a configuration that supports this setup, see [Dependency Graphs for pull request workflows](#dependency-graphs-for-pull-request-workflows).

### Making dependency graph failures cause Job failures

By default, if a failure is encountered when generating or submitting the dependency graph, the action will log the failure as a warning and continue.
This allows your workflow to be resilient to dependency graph failures, in case dependency graph production is a side-effect rather than the primary purpose of a workflow.

If instead you have a workflow that has a primary purpose to generate and submit a dependency graph, then it makes sense for this workflow to fail if the dependency
graph cannot be generated or submitted. You can enable this behaviour with the `dependency-graph-continue-on-failure` parameter, which defaults to `true`.

```yaml
# Ensure that the workflow Job will fail if the dependency graph cannot be submitted
- uses: gradle/gradle-build-action@v3
with:
dependency-graph: generate-and-submit
dependency-graph-continue-on-failure: false
```

### Using a custom plugin repository

By default, the action downloads the `github-dependency-graph-gradle-plugin` from the Gradle Plugin Portal (https://plugins.gradle.org). If your GitHub Actions environment does not have access to this URL, you can specify a custom plugin repository to use.
Do so by setting the `GRADLE_PLUGIN_REPOSITORY_URL` environment variable with your Gradle invocation.

```yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Gradle to generate and submit dependency graphs
uses: gradle/gradle-build-action@v2
with:
dependency-graph: generate-and-submit
- name: Run a build, resolving the 'dependency-graph' plugin from the plugin portal proxy
run: ./gradlew build
env:
GRADLE_PLUGIN_REPOSITORY_URL: "https://gradle-plugins-proxy.mycorp.com"
```

### Integrating the `dependency-review-action`

The GitHub [dependency-review-action](https://github.com/actions/dependency-review-action) helps you
understand dependency changes (and the security impact of these changes) for a pull request.
For the `dependency-review-action` to succeed, it must run _after_ the dependency graph has been submitted for a PR.

When using `generate-and-submit`, dependency graph files are submitted at the end of the job, after all steps have been
executed. For this reason, the `dependency-review-action` must be executed in a dependent job,
and not as a subsequent step in the job that generates the dependency graph.

Example of a pull request workflow that executes a build for a pull request and runs the `dependency-review-action`:

```yaml
name: PR check
on:
pull_request:
permissions:
contents: write
# Note that this permission will not be available if the PR is from a forked repository
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Gradle to generate and submit dependency graphs
uses: gradle/gradle-build-action@v2
with:
dependency-graph: generate-and-submit
- name: Run a build and generate the dependency graph which will be submitted post-job
run: ./gradlew build
dependency-review:
needs: build
runs-on: ubuntu-latest
- name: Perform dependency review
uses: actions/dependency-review-action@v4
```

See [Dependency Graphs for pull request workflows](#dependency-graphs-for-pull-request-workflows) for a more complex
(and less functional) example that will work for pull requests submitted from forked repositories.

## Limiting the scope of the dependency graph

At times it is helpful to limit the dependencies reported to GitHub, in order to security alerts for dependencies that don't form a critical part of your product.
For example, a vulnerability in the tool you use to generate documentation is unlikely to be as important as a vulnerability in one of your runtime dependencies.

There are a number of techniques you can employ to limit the scope of the generated dependency graph:
- [Don't generate a dependency graph for all Gradle executions](#choosing-which-gradle-invocations-will-generate-a-dependency-graph)
- [For a Gradle execution, filter which Gradle projects and configurations will contribute dependencies](#filtering-which-gradle-configurations-contribute-to-the-dependency-graph)
- [Use a separate workflow that only resolves the required dependencies](#use-a-dedicated-workflow-for-dependency-graph-generation)

> [!NOTE]
> Ideally, all dependencies involved in building and testing a project will be extracted and reported in a dependency graph.
> These dependencies would be assigned to different scopes (eg development, runtime, testing) and the GitHub UI would make it easy to opt-in to security alerts for different dependency scopes.
> However, this functionality does not yet exist.

### Choosing which Gradle invocations will generate a dependency graph

Once you enable the dependency graph support for a workflow job (via the `dependency-graph` parameter), dependencies will be collected and reported for all subsequent Gradle invocations.
If you have a Gradle build step that you want to exclude from dependency graph generation, you can set the `GITHUB_DEPENDENCY_GRAPH_ENABLED` environment variable to `false`.

```yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Gradle to generate and submit dependency graphs
uses: gradle/gradle-build-action@v2
with:
dependency-graph: generate-and-submit
- name: Build the app, generating a graph of dependencies required
run: ./gradlew :my-app:assemble
- name: Run all checks, disabling dependency graph generation
run: ./gradlew check
env:
GITHUB_DEPENDENCY_GRAPH_ENABLED: false
```

### Filtering which Gradle Configurations contribute to the dependency graph

If you do not want the dependency graph to include every dependency configuration in every project in your build, you can limit the
dependency extraction to a subset of these.

To restrict which Gradle subprojects contribute to the report, specify which projects to include via a regular expression.
You can provide this value via the `DEPENDENCY_GRAPH_INCLUDE_PROJECTS` environment variable or system property.

To restrict which Gradle configurations contribute to the report, you can filter configurations by name using a regular expression.
You can provide this value via the `DEPENDENCY_GRAPH_INCLUDE_CONFIGURATIONS` environment variable or system property.

For example, if you want to exclude dependencies in the `buildSrc` project, and only report on dependencies from the `runtimeClasspath` configuration,
you would use the following configuration:

```yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Gradle to generate and submit dependency graphs
uses: gradle/gradle-build-action@v2
with:
dependency-graph: generate-and-submit
- name: Run a build, generating the dependency graph from any resolved 'runtimeClasspath' configurations
run: ./gradlew build
env:
DEPENDENCY_GRAPH_INCLUDE_PROJECTS: "^:(?!buildSrc).*"
DEPENDENCY_GRAPH_INCLUDE_CONFIGURATIONS: runtimeClasspath
```

### Use a dedicated workflow for dependency graph generation

Instead of generating a dependency graph from your existing CI workflow, it's possible to create a separate dedicated workflow (or Job) that is intended for generating a dependency graph.
Such a workflow will still need to execute Gradle, but can do so in a way that is targeted at resolving the specific dependencies required.

For example, the following workflow will report those dependencies that are resolved in order to build the `distributionZip` for the `my-app` project. Test dependencies and other dependencies not required by the `distributionZip` will not be included.

```yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Gradle to generate and submit dependency graphs
uses: gradle/gradle-build-action@v2
with:
dependency-graph: generate-and-submit
- name: Build the distribution Zip for `my-app`
run: ./gradlew :my-app:distributionZip
```
Note that the above example will also include any `buildSrc` dependencies, dependencies resolved when configuring your Gradle build or dependencies resolved while applying plugin. All of these dependencies are resolved in the process of running the `distributionZip` task, and thus will form part of the generated dependency graph.

If this isn't desirable, you will still need to use the filtering mechanism described above.

## Dependency Graphs for pull request workflows

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
on:
pull_request:
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Gradle to generate and submit dependency graphs
uses: gradle/gradle-build-action@v2
with:
dependency-graph: generate-and-upload # Generate graphs and save as workflow artifacts
- name: Run a build, generating the dependency graph snapshot which will be submitted
run: ./gradlew build
```

***Dependent workflow file***
```yaml
name: submit-dependency-snapshot
on:
workflow_run:
workflows: ['run-build-and-generate-dependency-snapshot']
types: [completed]
permissions:
contents: write
jobs:
submit-dependency-graph:
runs-on: ubuntu-latest
steps:
- name: Retrieve dependency graph artifact and submit
uses: gradle/gradle-build-action@v2
with:
dependency-graph: download-and-submit # Download saved workflow artifacts and submit
```

### Integrating `dependency-review-action` for pull request workflows

The GitHub [dependency-review-action](https://github.com/actions/dependency-review-action) helps you
understand dependency changes (and the security impact of these changes) for a pull request.

To integrate the `dependency-review-action` into the pull request workflows above, a separate workflow should be added.
This workflow will be triggered directly on `pull_request`, but will need to wait until the dependency graph results are
submitted before the dependency review can complete. How long to wait is controlled by the `retry-on-snapshot-warnings` input parameters.

Here's an example of a separate "Dependency Review" workflow that will wait for 10 minutes for the PR check workflow to complete.

```yaml
name: dependency-review
on:
pull_request:
permissions:
contents: read
pull-requests: write
jobs:
dependency-review:
runs-on: ubuntu-latest
steps:
- name: 'Dependency Review'
uses: actions/dependency-review-action@v4
with:
retry-on-snapshot-warnings: true
retry-on-snapshot-warnings-timeout: 600
```

The `retry-on-snapshot-warnings-timeout` (in seconds) needs to be long enough to allow the entire `run-build-and-generate-dependency-snapshot` and `submit-dependency-snapshot` workflows (above) to complete.

## Gradle version compatibility

The GitHub Dependency Graph plugin should be compatible with all versions of Gradle >= 5.0, and has been tested against
Gradle versions "5.6.4", "6.9.4", "7.0.2", "7.6.2", "8.0.2" and the current Gradle release.

The plugin is compatible with running Gradle with the configuration-cache enabled. However, this support is
limited to Gradle "8.1.0" and later:
- With Gradle "8.0", the build should run successfully, but an empty dependency graph will be generated.
- With Gradle <= "7.6.4", the plugin will cause the build to fail with configuration-cache enabled.

To use this plugin with versions of Gradle older than "8.1.0", you'll need to invoke Gradle with the
configuration-cache disabled.

## Reducing storage costs for saved dependency graph artifacts

When `generate` or `generate-and-submit` is used with the action, the dependency graph that is generated is stored as a workflow artifact.
By default, these artifacts are retained for a period of 30 days (or as configured for the repository).
To reduce storage costs for these artifacts, you can set the `artifact-retention-days` value to a lower number.

```yaml
steps:
- name: Generate dependency graph, but only retain artifact for one day
uses: gradle/gradle-build-action@v2
with:
dependency-graph: generate
artifact-retention-days: 1
```

> The simplest (and recommended) way to generate a dependency graph is via a separate workflow
> using `gradle/actions/dependency-submission`. This action will attempt to detect all dependencies used by your build
> without building and testing the project itself.
>
> See the [dependency-submission documentation](https://github.com/gradle/actions/blob/main/dependency-submission/README.md) for up-to-date documentation.

For documentation on directly generating a dependency graph from a Gradle execution, see the
[setup-gradle docs](https://github.com/gradle/actions/blob/main/setup-gradle/README.md#github-dependency-graph-support) on this topic.

# Develocity plugin injection

Expand Down

0 comments on commit 4587492

Please sign in to comment.