gradle / gradle-build-action

Execute your Gradle build and trigger dependency submission
https://github.com/marketplace/actions/gradle-build-action
MIT License
679 stars 97 forks source link

How to handle dependency submission in multi-step build workflow? #843

Closed big-andy-coates closed 1 year ago

big-andy-coates commented 1 year ago

Hi,

I'm playing around with the new dependency submission feature (great to see this!) and I have a question about intended use / patterns when there are multiple calls to Gradle in the build.

For example:

name: CI
on: <stuff>

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@v2
      with:
        dependency-graph: generate-and-submit
    - name: Run a build, generating the dependency graph snapshot which will be submitted
      run: ./gradlew build
    - name: Publish
      if: <stuff>
      run: ./gradlew publish

In the above workflow Gradle will build two dependency reports, one for each of the ./gradlew calls.

Generally, this second report isn't intentional!

The situation is also confusing for users If they want to filter by configuration and/or project. If they naively just add the necessary DEPENDENCY_GRAPH_INCLUDE_CONFIGURATIONS and/or DEPENDENCY_GRAPH_INCLUDE_PROJECTS vars to the first build step, then only the first report is filtered. The second report is unfiltered, so all dependencies are submitted to GitHub. To correctly filter, users need to remember to set env vars on all Gradle steps and remember to keep them in sync going forward.

Question: what is the intended pattern to limit the build to generate only a single dependency report?

Maybe a second gradle/gradle-build-action step after the first build step? But then would this not require users to remember to keep the settings of these two steps insync?

bigdaz commented 1 year ago

Speaking with the GitHub team, they would rather that users default to publishing all of their dependencies, and are planning to add tools to make it easier to manage these.

But I understand that for now you are trying to publish a subset of dependencies to avoid getting vulnerability reports for dependencies that you consider unimportant.

One option you have is to use a separate workflow to generate the dependency graph, completely separate from your regular CI workflow. This would be similar to the way CodeQL works. This workflow would do as little computation as possible while resolving the necessary dependencies. For example: gradle :my-app:dependencies --configuration RuntimeClasspath.

To address your specific scenario, you can disable dependency graph generation for the "Publish" step with:

    - name: Publish
      if: <stuff>
      run: ./gradlew publish
      env:
         # This is set to 'true' by the 'gradle-build-action'
         GITHUB_DEPENDENCY_GRAPH_ENABLED: false

Under the hood this works because dependency graph plugin is applied via this init script.

PS Thanks for the questions. I'm currently working on improving the documentation around dependency-graph support, and this is prompting me to write the content!

big-andy-coates commented 1 year ago

Speaking with the GitHub team, they would rather that users default to publishing all of their dependencies, and are planning to add tools to make it easier to manage these.

But I understand that for now you are trying to publish a subset of dependencies to avoid getting vulnerability reports for dependencies that you consider unimportant.

Yep, that's what I'm doing until the GitHub tooling allows more filtering and control over alerting to make it practical to report everything.

One option you have is to use a separate workflow to generate the dependency graph, completely separate from your regular CI workflow. This would be similar to the way CodeQL works. This workflow would do as little computation as possible while resolving the necessary dependencies. For example: gradle :my-app:dependencies --configuration RuntimeClasspath.

Snap ;) This is what I ended up doing: https://github.com/creek-service/creek-base/blob/main/.github/workflows/dependencies.yml

PS Thanks for the questions. I'm currently working on improving the documentation around dependency-graph support, and this is prompting me to write the content!

Cool - looks like you're already planning on documenting, which is why I raised this issue.

Feel free to close this issue, or I'm happy to raise a PR for this issue documenting what we've discussed - might not be perfect, but maybe good enough for now, freeing you up to work on the code :)