diff --git a/README.md b/README.md index 69f9f2c..00c6267 100644 --- a/README.md +++ b/README.md @@ -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.

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