From 51f31c9882b6e5998e0df571096147a99842092b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Nov 2024 06:16:21 +0000 Subject: [PATCH 01/12] :seedling: Bump goreleaser/goreleaser-action from 6.0.0 to 6.1.0 (#4410) --- .github/workflows/goreleaser.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/goreleaser.yaml b/.github/workflows/goreleaser.yaml index 6ce61923d4c7..0690f1b780dc 100644 --- a/.github/workflows/goreleaser.yaml +++ b/.github/workflows/goreleaser.yaml @@ -52,7 +52,7 @@ jobs: run: echo "version_flags=$(./scripts/version-ldflags)" >> "$GITHUB_OUTPUT" - name: Run GoReleaser id: run-goreleaser - uses: goreleaser/goreleaser-action@286f3b13b1b49da4ac219696163fb8c1c93e1200 # v6.0.0 + uses: goreleaser/goreleaser-action@9ed2f89a662bf1735a48bc8557fd212fa902bebf # v6.1.0 with: args: release --clean env: From ea7cbdc45139a47b9000314325525f88b1635128 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 09:42:29 +0000 Subject: [PATCH 02/12] :seedling: Bump the github-actions group across 1 directory with 4 updates (#4421) --- .github/workflows/codeql-analysis.yml | 8 ++++---- .github/workflows/depsreview.yml | 2 +- .github/workflows/docker.yml | 2 +- .github/workflows/gitlab.yml | 4 ++-- .github/workflows/goreleaser.yaml | 2 +- .github/workflows/integration.yml | 6 +++--- .github/workflows/lint.yml | 2 +- .github/workflows/main.yml | 22 +++++++++++----------- .github/workflows/publishimage.yml | 2 +- .github/workflows/scorecard-analysis.yml | 2 +- .github/workflows/stale.yml | 2 +- .github/workflows/verify.yml | 2 +- 12 files changed, 28 insertions(+), 28 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index f711c2d09cfd..8b748afe3501 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -55,7 +55,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -73,7 +73,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@4f3212b61783c3c68e8309a0f18a699764811cda # v3.27.1 + uses: github/codeql-action/init@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5 with: languages: ${{ matrix.language }} queries: +security-extended @@ -85,7 +85,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@4f3212b61783c3c68e8309a0f18a699764811cda # v3.27.1 + uses: github/codeql-action/autobuild@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5 # ℹī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -99,4 +99,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4f3212b61783c3c68e8309a0f18a699764811cda # v3.27.1 + uses: github/codeql-action/analyze@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5 diff --git a/.github/workflows/depsreview.yml b/.github/workflows/depsreview.yml index 853e41a9c2bb..d32878a6de03 100644 --- a/.github/workflows/depsreview.yml +++ b/.github/workflows/depsreview.yml @@ -24,4 +24,4 @@ jobs: - name: 'Checkout Repository' uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: 'Dependency Review' - uses: actions/dependency-review-action@4081bf99e2866ebe428fc0477b69eb4fcda7220a # v4.4.0 + uses: actions/dependency-review-action@3b139cfc5fae8b618d3eae3675e383bb1769c019 # v4.5.0 diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index c2df237eacfb..866aefc5766d 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -72,7 +72,7 @@ jobs: steps: - name: Harden Runner if: (needs.docs_only_check.outputs.docs_only != 'true') - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - name: Clone the code diff --git a/.github/workflows/gitlab.yml b/.github/workflows/gitlab.yml index cf0abc476468..1c65c8959265 100644 --- a/.github/workflows/gitlab.yml +++ b/.github/workflows/gitlab.yml @@ -33,7 +33,7 @@ jobs: environment: gitlab steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - name: Clone the code @@ -86,7 +86,7 @@ jobs: command: make e2e-gitlab-token - name: codecov - uses: codecov/codecov-action@ab904c41d6ece82784817410c45d8b8c02684457 # 3.1.6 + uses: codecov/codecov-action@015f24e6818733317a2da2edd6290ab26238649a # 5.0.7 with: files: "*e2e-coverage.out" verbose: true diff --git a/.github/workflows/goreleaser.yaml b/.github/workflows/goreleaser.yaml index 0690f1b780dc..b20ed83fa062 100644 --- a/.github/workflows/goreleaser.yaml +++ b/.github/workflows/goreleaser.yaml @@ -34,7 +34,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 5d4aaaa2c8ca..a35c9bc1a694 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -31,7 +31,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -44,7 +44,7 @@ jobs: needs: [approve] steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - name: Clone the code @@ -87,7 +87,7 @@ jobs: command: make e2e-gh-token - name: codecov - uses: codecov/codecov-action@ab904c41d6ece82784817410c45d8b8c02684457 # 3.1.6 + uses: codecov/codecov-action@015f24e6818733317a2da2edd6290ab26238649a # 5.0.7 with: files: "*e2e-coverage.out" verbose: true diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 89d01fdf3e40..b5ac053da5b2 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -19,7 +19,7 @@ jobs: name: check-linter runs-on: ubuntu-latest steps: - - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + - uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 53988dd8adc6..5b13a3d24509 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -37,7 +37,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - name: Clone the code @@ -68,7 +68,7 @@ jobs: - name: Run unit-tests run: make unit-test - name: Upload codecoverage - uses: codecov/codecov-action@ab904c41d6ece82784817410c45d8b8c02684457 # 3.1.6 + uses: codecov/codecov-action@015f24e6818733317a2da2edd6290ab26238649a # 5.0.7 with: files: ./unit-coverage.out verbose: true @@ -83,7 +83,7 @@ jobs: timeout_minutes: 30 command: make e2e-pat - name: codecov - uses: codecov/codecov-action@ab904c41d6ece82784817410c45d8b8c02684457 # 2.1.0 + uses: codecov/codecov-action@015f24e6818733317a2da2edd6290ab26238649a # 2.1.0 if: ${{ github.event_name != 'pull_request' || github.actor != 'dependabot[bot]' }} with: files: "*e2e-coverage.out" @@ -95,7 +95,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -143,7 +143,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - name: Clone the code @@ -172,7 +172,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -221,7 +221,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - name: Cache builds @@ -260,7 +260,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -302,7 +302,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - name: Clone the code @@ -330,7 +330,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -365,7 +365,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs diff --git a/.github/workflows/publishimage.yml b/.github/workflows/publishimage.yml index 57dad25aaeab..5943f2b8252b 100644 --- a/.github/workflows/publishimage.yml +++ b/.github/workflows/publishimage.yml @@ -36,7 +36,7 @@ jobs: COSIGN_EXPERIMENTAL: "true" steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs diff --git a/.github/workflows/scorecard-analysis.yml b/.github/workflows/scorecard-analysis.yml index 509c6d2d37af..c26dc0d3277a 100644 --- a/.github/workflows/scorecard-analysis.yml +++ b/.github/workflows/scorecard-analysis.yml @@ -51,6 +51,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@4f3212b61783c3c68e8309a0f18a699764811cda # v3.27.1 + uses: github/codeql-action/upload-sarif@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5 with: sarif_file: results.sarif diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 31e508b084fa..34fb2167c96d 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -27,7 +27,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index d66b003a3a1e..0517e04f0874 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -26,7 +26,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs From 45b4651a4d73af26974e20d4736f073063bec3d2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 07:51:41 +0000 Subject: [PATCH 03/12] :seedling: Bump github.com/google/osv-scanner from 1.9.0 to 1.9.1 (#4405) --- go.mod | 18 +++++++++--------- go.sum | 36 ++++++++++++++++++------------------ 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/go.mod b/go.mod index 0cd8fd7ac8ea..6a70fab61d0e 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( go.opencensus.io v0.24.0 gocloud.dev v0.40.0 golang.org/x/text v0.19.0 - golang.org/x/tools v0.25.0 // indirect + golang.org/x/tools v0.26.0 // indirect google.golang.org/genproto v0.0.0-20241015192408-796eee8c2d53 // indirect google.golang.org/protobuf v1.35.1 gopkg.in/yaml.v2 v2.4.0 @@ -42,7 +42,7 @@ require ( github.com/caarlos0/env/v6 v6.10.0 github.com/gobwas/glob v0.2.3 github.com/google/go-github/v53 v53.2.0 - github.com/google/osv-scanner v1.9.0 + github.com/google/osv-scanner v1.9.1 github.com/mcuadros/go-jsonschema-generator v0.0.0-20200330054847-ba7a369d4303 github.com/onsi/ginkgo/v2 v2.20.2 github.com/otiai10/copy v1.14.0 @@ -57,10 +57,10 @@ require ( cloud.google.com/go/kms v1.20.0 // indirect cloud.google.com/go/longrunning v0.6.1 // indirect dario.cat/mergo v1.0.0 // indirect - deps.dev/api/v3 v3.0.0-20240923041156-0312db85d6d6 // indirect - deps.dev/util/maven v0.0.0-20240923041156-0312db85d6d6 // indirect - deps.dev/util/resolve v0.0.0-20240923041156-0312db85d6d6 // indirect - deps.dev/util/semver v0.0.0-20240923041156-0312db85d6d6 // indirect + deps.dev/api/v3 v3.0.0-20241010035105-b3ba03369df1 // indirect + deps.dev/util/maven v0.0.0-20241010035105-b3ba03369df1 // indirect + deps.dev/util/resolve v0.0.0-20241010035105-b3ba03369df1 // indirect + deps.dev/util/semver v0.0.0-20241010035105-b3ba03369df1 // indirect github.com/BurntSushi/toml v1.4.0 // indirect github.com/CycloneDX/cyclonedx-go v0.9.1 // indirect github.com/anchore/go-struct-converter v0.0.0-20230627203149-c72ef8859ca9 // indirect @@ -88,7 +88,7 @@ require ( github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/ianlancetaylor/demangle v0.0.0-20240912202439-0a2b6291aafd // indirect - github.com/jedib0t/go-pretty/v6 v6.5.9 // indirect + github.com/jedib0t/go-pretty/v6 v6.6.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect @@ -106,7 +106,7 @@ require ( github.com/skeema/knownhosts v1.2.2 // indirect github.com/spdx/gordf v0.0.0-20221230105357-b735bd5aac89 // indirect github.com/spdx/tools-golang v0.5.5 // indirect - github.com/tidwall/gjson v1.17.3 // indirect + github.com/tidwall/gjson v1.18.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/zeebo/xxh3 v1.0.2 // indirect @@ -183,7 +183,7 @@ require ( github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect golang.org/x/crypto v0.28.0 // indirect - golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect + golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect golang.org/x/net v0.30.0 // indirect golang.org/x/oauth2 v0.23.0 golang.org/x/sync v0.8.0 // indirect diff --git a/go.sum b/go.sum index 2d66095854f8..07b2d6ba459a 100644 --- a/go.sum +++ b/go.sum @@ -53,14 +53,14 @@ contrib.go.opencensus.io/exporter/stackdriver v0.13.14 h1:zBakwHardp9Jcb8sQHcHpX contrib.go.opencensus.io/exporter/stackdriver v0.13.14/go.mod h1:5pSSGY0Bhuk7waTHuDf4aQ8D2DrhgETRo9fy6k3Xlzc= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -deps.dev/api/v3 v3.0.0-20240923041156-0312db85d6d6 h1:O7bwO5zXB+avzptz7/f7YKFoj+tWX8Ukw8JN71A33ko= -deps.dev/api/v3 v3.0.0-20240923041156-0312db85d6d6/go.mod h1:DyBY3wNVqRCwvb4tLvz6LL/FupH3FMflEROyQAv2Vi0= -deps.dev/util/maven v0.0.0-20240923041156-0312db85d6d6 h1:rxpC2qP0yZ32z87p0QCpsk6OZNHEGqBL92be7IgaqRI= -deps.dev/util/maven v0.0.0-20240923041156-0312db85d6d6/go.mod h1:SBW3EribdkZYk6zxi5oVn/ZECvi4ixb7EGgEWfSimNk= -deps.dev/util/resolve v0.0.0-20240923041156-0312db85d6d6 h1:dMhUGfcJOGva/eTVViPsodd9PhtTN8gGTquylrzeqno= -deps.dev/util/resolve v0.0.0-20240923041156-0312db85d6d6/go.mod h1:XXi6yRYqhtxw5DvGX/mbG6fHSLn8OgoPowNd8EAxDgk= -deps.dev/util/semver v0.0.0-20240923041156-0312db85d6d6 h1:Z//oau8lRNolCKSTeRDrfi8+sPYE76qdAX8ym/MR4Eo= -deps.dev/util/semver v0.0.0-20240923041156-0312db85d6d6/go.mod h1:jkcH+k02gWHBiZ7G4OnUOkSZ6WDq54Pt5DrOA8FN8Uo= +deps.dev/api/v3 v3.0.0-20241010035105-b3ba03369df1 h1:qvrLinmQrkOLmguTE9FpRfC/e2iud/eVMWigXXTdrdA= +deps.dev/api/v3 v3.0.0-20241010035105-b3ba03369df1/go.mod h1:DyBY3wNVqRCwvb4tLvz6LL/FupH3FMflEROyQAv2Vi0= +deps.dev/util/maven v0.0.0-20241010035105-b3ba03369df1 h1:PWgfyz6h15n4dbcSAL/3lSiXl8foQZCzUWUqEjNLNvI= +deps.dev/util/maven v0.0.0-20241010035105-b3ba03369df1/go.mod h1:SBW3EribdkZYk6zxi5oVn/ZECvi4ixb7EGgEWfSimNk= +deps.dev/util/resolve v0.0.0-20241010035105-b3ba03369df1 h1:nHefSxxfjdmo+zn/8fEcfSUkTXi+LKnBNvul21ZI9qw= +deps.dev/util/resolve v0.0.0-20241010035105-b3ba03369df1/go.mod h1:XXi6yRYqhtxw5DvGX/mbG6fHSLn8OgoPowNd8EAxDgk= +deps.dev/util/semver v0.0.0-20241010035105-b3ba03369df1 h1:t4P0dCCNIrV84B5d7kOIAzji+HrO303Nrw9BB4ktBy0= +deps.dev/util/semver v0.0.0-20241010035105-b3ba03369df1/go.mod h1:jkcH+k02gWHBiZ7G4OnUOkSZ6WDq54Pt5DrOA8FN8Uo= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/Azure/azure-sdk-for-go v35.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v38.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= @@ -407,8 +407,8 @@ github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPg github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc= github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0= -github.com/google/osv-scanner v1.9.0 h1:srb17XR4Q6EVojAPDMQwkBVR5jMx0fGw2DFzTn4IUiI= -github.com/google/osv-scanner v1.9.0/go.mod h1:AFmX40ZQOGpkCpqbDAtIjtVP4FMlA0OTWAxRBH1G7/I= +github.com/google/osv-scanner v1.9.1 h1:L/j81YXO+DuhBd+v2eYwpDTfmUpMLryItSv7SXA1Db4= +github.com/google/osv-scanner v1.9.1/go.mod h1:VNJG6+N9l6Y1dcaGgK/a7D4g9hnxakn0DBKGH0Aw+mQ= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -491,8 +491,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jedib0t/go-pretty/v6 v6.5.9 h1:ACteMBRrrmm1gMsXe9PSTOClQ63IXDUt03H5U+UV8OU= -github.com/jedib0t/go-pretty/v6 v6.5.9/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E= +github.com/jedib0t/go-pretty/v6 v6.6.0 h1:wmZVuAcEkZRT+Aq1xXpE8IGat4vE5WXOMmBpbQqERXw= +github.com/jedib0t/go-pretty/v6 v6.6.0/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= @@ -750,8 +750,8 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8 github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/terminalstatic/go-xsd-validate v0.1.5 h1:RqpJnf6HGE2CB/lZB1A8BYguk8uRtcvYAPLCF15qguo= github.com/terminalstatic/go-xsd-validate v0.1.5/go.mod h1:18lsvYFofBflqCrvo1umpABZ99+GneNTw2kEEc8UPJw= -github.com/tidwall/gjson v1.17.3 h1:bwWLZU7icoKRG+C+0PNwIKC6FCJO/Q3p2pZvuP0jN94= -github.com/tidwall/gjson v1.17.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= +github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= @@ -851,8 +851,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1094,8 +1094,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= -golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= -golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= +golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= +golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= golang.org/x/vuln v1.0.4 h1:SP0mPeg2PmGCu03V+61EcQiOjmpri2XijexKdzv8Z1I= golang.org/x/vuln v1.0.4/go.mod h1:NbJdUQhX8jY++FtuhrXs2Eyx0yePo9pF7nPlIjo9aaQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 70104adf958c9a3a16238a20882cdfbd63bec63f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 09:14:26 +0000 Subject: [PATCH 04/12] :seedling: Bump github.com/go-git/go-billy/v5 from 5.5.0 to 5.6.0 (#4418) --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 6a70fab61d0e..e4dc6725ab9c 100644 --- a/go.mod +++ b/go.mod @@ -67,7 +67,7 @@ require ( github.com/apache/arrow/go/v15 v15.0.2 // indirect github.com/cloudflare/circl v1.3.7 // indirect github.com/containerd/typeurl/v2 v2.2.0 // indirect - github.com/cyphar/filepath-securejoin v0.2.4 // indirect + github.com/cyphar/filepath-securejoin v0.2.5 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dghubble/trie v0.1.0 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect @@ -150,7 +150,7 @@ require ( github.com/emirpasic/gods v1.18.1 // indirect github.com/fatih/color v1.17.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-git/go-billy/v5 v5.5.0 + github.com/go-git/go-billy/v5 v5.6.0 github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.5.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect diff --git a/go.sum b/go.sum index 07b2d6ba459a..70073c9c2b18 100644 --- a/go.sum +++ b/go.sum @@ -214,8 +214,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= -github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/cyphar/filepath-securejoin v0.2.5 h1:6iR5tXJ/e6tJZzzdMc1km3Sa7RRIVBKAK32O2s7AYfo= +github.com/cyphar/filepath-securejoin v0.2.5/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo= github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -280,8 +280,8 @@ github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE= github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= -github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-billy/v5 v5.6.0 h1:w2hPNtoehvJIxR00Vb4xX94qHQi/ApZfX+nBE2Cjio8= +github.com/go-git/go-billy/v5 v5.6.0/go.mod h1:sFDq7xD3fn3E0GOwUSZqHo9lrkmx8xJhA0ZrfvjBRGM= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= From feaea40ed37fdeddc17a63bf4afb473e1e1afcd7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 09:46:28 +0000 Subject: [PATCH 05/12] :seedling: Bump the distroless group across 6 directories with 1 update (#4425) --- clients/githubrepo/roundtripper/tokens/server/Dockerfile | 2 +- cron/internal/bq/Dockerfile | 2 +- cron/internal/cii/Dockerfile | 2 +- cron/internal/controller/Dockerfile | 2 +- cron/internal/webhook/Dockerfile | 2 +- cron/internal/worker/Dockerfile | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/githubrepo/roundtripper/tokens/server/Dockerfile b/clients/githubrepo/roundtripper/tokens/server/Dockerfile index f463d7662a02..ceeb8e9a0b3f 100644 --- a/clients/githubrepo/roundtripper/tokens/server/Dockerfile +++ b/clients/githubrepo/roundtripper/tokens/server/Dockerfile @@ -24,6 +24,6 @@ ARG TARGETOS ARG TARGETARCH RUN CGO_ENABLED=0 make build-github-server -FROM gcr.io/distroless/base:nonroot@sha256:350980ee07b2fc28336bb730cdb02b7c83d4a4d7832b1a49c827c8cc28f7f06b +FROM gcr.io/distroless/base:nonroot@sha256:6d4a4f40e93615df1677463ca56456379cc3a4e2359308c9e72bc60ffc4a12a9 COPY --from=authserver /src/clients/githubrepo/roundtripper/tokens/server/github-auth-server clients/githubrepo/roundtripper/tokens/server/github-auth-server ENTRYPOINT ["clients/githubrepo/roundtripper/tokens/server/github-auth-server"] diff --git a/cron/internal/bq/Dockerfile b/cron/internal/bq/Dockerfile index 5dbaeffac686..f2224f29b0cd 100644 --- a/cron/internal/bq/Dockerfile +++ b/cron/internal/bq/Dockerfile @@ -24,6 +24,6 @@ ARG TARGETOS ARG TARGETARCH RUN CGO_ENABLED=0 make build-bq-transfer -FROM gcr.io/distroless/base:nonroot@sha256:350980ee07b2fc28336bb730cdb02b7c83d4a4d7832b1a49c827c8cc28f7f06b +FROM gcr.io/distroless/base:nonroot@sha256:6d4a4f40e93615df1677463ca56456379cc3a4e2359308c9e72bc60ffc4a12a9 COPY --from=transfer /src/cron/internal/bq/data-transfer cron/internal/bq/data-transfer ENTRYPOINT ["cron/internal/bq/data-transfer"] diff --git a/cron/internal/cii/Dockerfile b/cron/internal/cii/Dockerfile index 1fea1f1e3e09..2652f138713a 100644 --- a/cron/internal/cii/Dockerfile +++ b/cron/internal/cii/Dockerfile @@ -24,6 +24,6 @@ ARG TARGETOS ARG TARGETARCH RUN CGO_ENABLED=0 make build-cii-worker -FROM gcr.io/distroless/base:nonroot@sha256:350980ee07b2fc28336bb730cdb02b7c83d4a4d7832b1a49c827c8cc28f7f06b +FROM gcr.io/distroless/base:nonroot@sha256:6d4a4f40e93615df1677463ca56456379cc3a4e2359308c9e72bc60ffc4a12a9 COPY --from=cii /src/cron/internal/cii/cii-worker cron/internal/cii/cii-worker ENTRYPOINT ["cron/internal/cii/cii-worker"] diff --git a/cron/internal/controller/Dockerfile b/cron/internal/controller/Dockerfile index 95ebe69bcfa3..fd88ad90248f 100644 --- a/cron/internal/controller/Dockerfile +++ b/cron/internal/controller/Dockerfile @@ -30,7 +30,7 @@ ARG TARGETOS ARG TARGETARCH RUN CGO_ENABLED=0 make build-controller -FROM gcr.io/distroless/base:nonroot@sha256:350980ee07b2fc28336bb730cdb02b7c83d4a4d7832b1a49c827c8cc28f7f06b +FROM gcr.io/distroless/base:nonroot@sha256:6d4a4f40e93615df1677463ca56456379cc3a4e2359308c9e72bc60ffc4a12a9 COPY ./cron/internal/data/projects*csv cron/internal/data/ COPY ./cron/internal/data/gitlab-projects-releasetest.csv cron/internal/data/ COPY ./cron/internal/data/gitlab-projects.csv cron/internal/data/ diff --git a/cron/internal/webhook/Dockerfile b/cron/internal/webhook/Dockerfile index a6e8b42525a9..b773176bd548 100644 --- a/cron/internal/webhook/Dockerfile +++ b/cron/internal/webhook/Dockerfile @@ -24,6 +24,6 @@ ARG TARGETOS ARG TARGETARCH RUN CGO_ENABLED=0 make build-webhook -FROM gcr.io/distroless/base:nonroot@sha256:350980ee07b2fc28336bb730cdb02b7c83d4a4d7832b1a49c827c8cc28f7f06b +FROM gcr.io/distroless/base:nonroot@sha256:6d4a4f40e93615df1677463ca56456379cc3a4e2359308c9e72bc60ffc4a12a9 COPY --from=webhook /src/cron/internal/webhook/webhook cron/internal/webhook/webhook ENTRYPOINT ["cron/internal/webhook/webhook"] diff --git a/cron/internal/worker/Dockerfile b/cron/internal/worker/Dockerfile index 2812395dbb82..d27cfa103b06 100644 --- a/cron/internal/worker/Dockerfile +++ b/cron/internal/worker/Dockerfile @@ -24,6 +24,6 @@ ARG TARGETOS ARG TARGETARCH RUN CGO_ENABLED=0 make build-worker -FROM gcr.io/distroless/base:nonroot@sha256:350980ee07b2fc28336bb730cdb02b7c83d4a4d7832b1a49c827c8cc28f7f06b +FROM gcr.io/distroless/base:nonroot@sha256:6d4a4f40e93615df1677463ca56456379cc3a4e2359308c9e72bc60ffc4a12a9 COPY --from=worker /src/cron/internal/worker/worker cron/internal/worker/worker ENTRYPOINT ["cron/internal/worker/worker"] From cae6d48116ef3132548c30fe36b9f5b2e89b17a0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 10:43:35 +0000 Subject: [PATCH 06/12] :seedling: Bump github.com/moby/buildkit from 0.16.0 to 0.18.0 (#4424) --- go.mod | 9 +++++---- go.sum | 18 ++++++++++-------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index e4dc6725ab9c..2f667e599118 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/grafeas/kritis v0.2.3-0.20210120183821-faeba81c520c github.com/h2non/filetype v1.1.3 github.com/jszwec/csvutil v1.10.0 - github.com/moby/buildkit v0.16.0 + github.com/moby/buildkit v0.18.0 github.com/olekukonko/tablewriter v0.0.5 github.com/onsi/gomega v1.35.1 github.com/rhysd/actionlint v1.7.3 @@ -66,7 +66,7 @@ require ( github.com/anchore/go-struct-converter v0.0.0-20230627203149-c72ef8859ca9 // indirect github.com/apache/arrow/go/v15 v15.0.2 // indirect github.com/cloudflare/circl v1.3.7 // indirect - github.com/containerd/typeurl/v2 v2.2.0 // indirect + github.com/containerd/typeurl/v2 v2.2.3 // indirect github.com/cyphar/filepath-securejoin v0.2.5 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dghubble/trie v0.1.0 // indirect @@ -101,6 +101,7 @@ require ( github.com/pandatix/go-cvss v0.6.2 // indirect github.com/pierrec/lz4/v4 v4.1.21 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect + github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/prometheus/prometheus v0.54.0 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect github.com/skeema/knownhosts v1.2.2 // indirect @@ -144,7 +145,7 @@ require ( github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be // indirect github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect - github.com/docker/cli v27.2.1+incompatible // indirect + github.com/docker/cli v27.4.0-rc.2+incompatible // indirect github.com/docker/distribution v2.8.3+incompatible // indirect github.com/docker/docker-credential-helpers v0.8.2 // indirect github.com/emirpasic/gods v1.18.1 // indirect @@ -165,7 +166,7 @@ require ( github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect - github.com/klauspost/compress v1.17.9 // indirect + github.com/klauspost/compress v1.17.11 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect diff --git a/go.sum b/go.sum index 70073c9c2b18..419539dfbb55 100644 --- a/go.sum +++ b/go.sum @@ -197,8 +197,8 @@ github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be/go.mod github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G/ZW/0kEe2oEKCdS/ZxIyoCU= github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk= -github.com/containerd/typeurl/v2 v2.2.0 h1:6NBDbQzr7I5LHgp34xAXYF5DOTQDn05X58lsPEmzLso= -github.com/containerd/typeurl/v2 v2.2.0/go.mod h1:8XOOxnyatxSWuG8OfsZXVnAF4iZfedjS/8UHSPJnX4g= +github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40= +github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -228,8 +228,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/cli v27.2.1+incompatible h1:U5BPtiD0viUzjGAjV1p0MGB8eVA3L3cbIrnyWmSJI70= -github.com/docker/cli v27.2.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v27.4.0-rc.2+incompatible h1:A0GZwegDlt2wdt3tpmrUzkVOZmbhvd7i05wPSf7Oo74= +github.com/docker/cli v27.4.0-rc.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= @@ -523,8 +523,8 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -577,8 +577,8 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4 github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/moby/buildkit v0.16.0 h1:wOVBj1o5YNVad/txPQNXUXdelm7Hs/i0PUFjzbK0VKE= -github.com/moby/buildkit v0.16.0/go.mod h1:Xqx/5GlrqE1yIRORk0NSCVDFpQAU1WjlT6KHYZdisIQ= +github.com/moby/buildkit v0.18.0 h1:KSelhNINJcNA3FCWBbGCytvicjP+kjU5kZlZhkTUkVo= +github.com/moby/buildkit v0.18.0/go.mod h1:vCR5CX8NGsPTthTg681+9kdmfvkvqJBXEv71GZe5msU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -645,6 +645,8 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= From cdfb58b4930d17b82b04d3f000d6901ddcf1d621 Mon Sep 17 00:00:00 2001 From: Luke Harrison Date: Mon, 2 Dec 2024 16:12:51 -0500 Subject: [PATCH 07/12] :sparkles: Allow incomplete local checks (#4423) * :sparkles: allow incomplete localdir checks (#3832) Signed-off-by: Luke Harrison * :sparkles: fixes as per @spencerschrock (#3832) Signed-off-by: Luke Harrison * :sparkles: fixed linting issues (#3832) Signed-off-by: Luke Harrison --------- Signed-off-by: Luke Harrison Signed-off-by: Luke Harrison --- checks/dangerous_workflow.go | 2 +- checks/fuzzing.go | 5 ++- checks/license.go | 1 + checks/packaging.go | 23 ++++++++++++-- checks/permissions.go | 2 +- checks/pinned_dependencies.go | 2 +- checks/raw/fuzzing.go | 10 ++++++ checks/raw/github/packaging.go | 9 +++++- checks/raw/sast.go | 5 +++ checks/sast.go | 5 ++- checks/security_policy.go | 1 + clients/localdir/client.go | 57 +++++++++++++++++----------------- cmd/root.go | 2 ++ policy/policy_test.go | 2 +- 14 files changed, 88 insertions(+), 38 deletions(-) diff --git a/checks/dangerous_workflow.go b/checks/dangerous_workflow.go index 61e7b337affe..7dae1cce40ef 100644 --- a/checks/dangerous_workflow.go +++ b/checks/dangerous_workflow.go @@ -29,8 +29,8 @@ const CheckDangerousWorkflow = "Dangerous-Workflow" //nolint:gochecknoinits func init() { supportedRequestTypes := []checker.RequestType{ - checker.FileBased, checker.CommitBased, + checker.FileBased, } if err := registerCheck(CheckDangerousWorkflow, DangerousWorkflow, supportedRequestTypes); err != nil { // this should never happen diff --git a/checks/fuzzing.go b/checks/fuzzing.go index 9f727fc6570b..0a55e0253c1c 100644 --- a/checks/fuzzing.go +++ b/checks/fuzzing.go @@ -28,7 +28,10 @@ const CheckFuzzing = "Fuzzing" //nolint:gochecknoinits func init() { - if err := registerCheck(CheckFuzzing, Fuzzing, nil); err != nil { + supportedRequestTypes := []checker.RequestType{ + checker.FileBased, + } + if err := registerCheck(CheckFuzzing, Fuzzing, supportedRequestTypes); err != nil { // this should never happen panic(err) } diff --git a/checks/license.go b/checks/license.go index 79609a1e28fb..ec9e0d3ac77b 100644 --- a/checks/license.go +++ b/checks/license.go @@ -30,6 +30,7 @@ const CheckLicense = "License" func init() { supportedRequestTypes := []checker.RequestType{ checker.CommitBased, + checker.FileBased, } if err := registerCheck(CheckLicense, License, supportedRequestTypes); err != nil { // this should never happen diff --git a/checks/packaging.go b/checks/packaging.go index 59c2762e288c..8b935e9e45f6 100644 --- a/checks/packaging.go +++ b/checks/packaging.go @@ -21,6 +21,7 @@ import ( "github.com/ossf/scorecard/v5/checks/raw/gitlab" "github.com/ossf/scorecard/v5/clients/githubrepo" "github.com/ossf/scorecard/v5/clients/gitlabrepo" + "github.com/ossf/scorecard/v5/clients/localdir" sce "github.com/ossf/scorecard/v5/errors" "github.com/ossf/scorecard/v5/probes" "github.com/ossf/scorecard/v5/probes/zrunner" @@ -31,7 +32,10 @@ const CheckPackaging = "Packaging" //nolint:gochecknoinits func init() { - if err := registerCheck(CheckPackaging, Packaging, nil); err != nil { + supportedRequestTypes := []checker.RequestType{ + checker.FileBased, + } + if err := registerCheck(CheckPackaging, Packaging, supportedRequestTypes); err != nil { // this should never happen panic(err) } @@ -39,10 +43,23 @@ func init() { // Packaging runs Packaging check. func Packaging(c *checker.CheckRequest) checker.CheckResult { - var rawData checker.PackagingData - var err error + var rawData, rawDataGithub, rawDataGitlab checker.PackagingData + var err, errGithub, errGitlab error switch v := c.RepoClient.(type) { + case *localdir.Client: + // Performing both packaging checks since we dont know when local + rawDataGithub, errGithub = github.Packaging(c) + rawDataGitlab, errGitlab = gitlab.Packaging(c) + // Appending results of checks + rawData.Packages = append(rawData.Packages, rawDataGithub.Packages...) + rawData.Packages = append(rawData.Packages, rawDataGitlab.Packages...) + // checking for errors + if errGithub != nil { + err = errGithub + } else if errGitlab != nil { + err = errGitlab + } case *githubrepo.Client: rawData, err = github.Packaging(c) case *gitlabrepo.Client: diff --git a/checks/permissions.go b/checks/permissions.go index 3014d8997b80..e9fa1b150827 100644 --- a/checks/permissions.go +++ b/checks/permissions.go @@ -29,8 +29,8 @@ const CheckTokenPermissions = "Token-Permissions" //nolint:gochecknoinits func init() { supportedRequestTypes := []checker.RequestType{ - checker.FileBased, checker.CommitBased, + checker.FileBased, } if err := registerCheck(CheckTokenPermissions, TokenPermissions, supportedRequestTypes); err != nil { // This should never happen. diff --git a/checks/pinned_dependencies.go b/checks/pinned_dependencies.go index a82cd6e93732..8a7ac0cdc8b2 100644 --- a/checks/pinned_dependencies.go +++ b/checks/pinned_dependencies.go @@ -29,8 +29,8 @@ const CheckPinnedDependencies = "Pinned-Dependencies" //nolint:gochecknoinits func init() { supportedRequestTypes := []checker.RequestType{ - checker.FileBased, checker.CommitBased, + checker.FileBased, } if err := registerCheck(CheckPinnedDependencies, PinningDependencies, supportedRequestTypes); err != nil { // This should never happen. diff --git a/checks/raw/fuzzing.go b/checks/raw/fuzzing.go index f4475e729d4b..5d30e5da1c9b 100644 --- a/checks/raw/fuzzing.go +++ b/checks/raw/fuzzing.go @@ -338,6 +338,8 @@ func getProminentLanguages(langs []clients.Language) []clients.LanguageName { numLangs := len(langs) if numLangs == 0 { return nil + } else if len(langs) == 1 && langs[0].Name == clients.All { + return getAllLanguages() } totalLoC := 0 // Use a map to record languages and their lines of code to drop potential duplicates. @@ -361,6 +363,14 @@ func getProminentLanguages(langs []clients.Language) []clients.LanguageName { return ret } +func getAllLanguages() []clients.LanguageName { + allLanguages := make([]clients.LanguageName, 0, len(languageFuzzSpecs)) + for l := range languageFuzzSpecs { + allLanguages = append(allLanguages, l) + } + return allLanguages +} + func propertyBasedDescription(language string) *string { s := fmt.Sprintf("Property-based testing in %s generates test instances randomly or exhaustively "+ "and test that specific properties are satisfied.", language) diff --git a/checks/raw/github/packaging.go b/checks/raw/github/packaging.go index 4deb99563a9f..5aa02bd8bd9f 100644 --- a/checks/raw/github/packaging.go +++ b/checks/raw/github/packaging.go @@ -15,6 +15,7 @@ package github import ( + "errors" "fmt" "io" "path/filepath" @@ -23,6 +24,7 @@ import ( "github.com/ossf/scorecard/v5/checker" "github.com/ossf/scorecard/v5/checks/fileparser" + "github.com/ossf/scorecard/v5/clients" "github.com/ossf/scorecard/v5/finding" ) @@ -73,7 +75,12 @@ func Packaging(c *checker.CheckRequest) (checker.PackagingData, error) { runs, err := c.RepoClient.ListSuccessfulWorkflowRuns(filepath.Base(fp)) if err != nil { - return data, fmt.Errorf("Client.Actions.ListWorkflowRunsByFileName: %w", err) + // assume the workflow will have run for localdir client + if errors.Is(err, clients.ErrUnsupportedFeature) { + runs = append(runs, clients.WorkflowRun{}) + } else { + return data, fmt.Errorf("Client.Actions.ListWorkflowRunsByFileName: %w", err) + } } if len(runs) > 0 { diff --git a/checks/raw/sast.go b/checks/raw/sast.go index 1806adcaeb97..0d654c2c1182 100644 --- a/checks/raw/sast.go +++ b/checks/raw/sast.go @@ -28,6 +28,7 @@ import ( "github.com/ossf/scorecard/v5/checker" "github.com/ossf/scorecard/v5/checks/fileparser" + "github.com/ossf/scorecard/v5/clients" sce "github.com/ossf/scorecard/v5/errors" "github.com/ossf/scorecard/v5/finding" ) @@ -92,6 +93,10 @@ func sastToolInCheckRuns(c *checker.CheckRequest) ([]checker.SASTCommit, error) var sastCommits []checker.SASTCommit commits, err := c.RepoClient.ListCommits() if err != nil { + // ignoring check for local dir + if errors.Is(err, clients.ErrUnsupportedFeature) { + return sastCommits, nil + } return sastCommits, sce.WithMessage(sce.ErrScorecardInternal, fmt.Sprintf("RepoClient.ListCommits: %v", err)) } diff --git a/checks/sast.go b/checks/sast.go index f09a6ba4d7a0..05f20846c1db 100644 --- a/checks/sast.go +++ b/checks/sast.go @@ -28,7 +28,10 @@ const CheckSAST = "SAST" //nolint:gochecknoinits func init() { - if err := registerCheck(CheckSAST, SAST, nil); err != nil { + supportedRequestTypes := []checker.RequestType{ + checker.FileBased, + } + if err := registerCheck(CheckSAST, SAST, supportedRequestTypes); err != nil { // This should never happen. panic(err) } diff --git a/checks/security_policy.go b/checks/security_policy.go index dd292494930c..00118725d603 100644 --- a/checks/security_policy.go +++ b/checks/security_policy.go @@ -30,6 +30,7 @@ const CheckSecurityPolicy = "Security-Policy" func init() { supportedRequestTypes := []checker.RequestType{ checker.CommitBased, + checker.FileBased, } if err := registerCheck(CheckSecurityPolicy, SecurityPolicy, supportedRequestTypes); err != nil { // This should never happen. diff --git a/clients/localdir/client.go b/clients/localdir/client.go index eb270f10b56e..e3c18eb4c15d 100644 --- a/clients/localdir/client.go +++ b/clients/localdir/client.go @@ -34,12 +34,12 @@ import ( ) var ( - _ clients.RepoClient = &localDirClient{} + _ clients.RepoClient = &Client{} errInputRepoType = errors.New("input repo should be of type repoLocal") ) //nolint:govet -type localDirClient struct { +type Client struct { logger *log.Logger ctx context.Context path string @@ -50,7 +50,7 @@ type localDirClient struct { } // InitRepo sets up the local repo. -func (client *localDirClient) InitRepo(inputRepo clients.Repo, commitSHA string, commitDepth int) error { +func (client *Client) InitRepo(inputRepo clients.Repo, commitSHA string, commitDepth int) error { localRepo, ok := inputRepo.(*Repo) if !ok { return fmt.Errorf("%w: %v", errInputRepoType, inputRepo) @@ -66,12 +66,12 @@ func (client *localDirClient) InitRepo(inputRepo clients.Repo, commitSHA string, } // URI implements RepoClient.URI. -func (client *localDirClient) URI() string { +func (client *Client) URI() string { return fmt.Sprintf("file://%s", client.path) } // IsArchived implements RepoClient.IsArchived. -func (client *localDirClient) IsArchived() (bool, error) { +func (client *Client) IsArchived() (bool, error) { return false, fmt.Errorf("IsArchived: %w", clients.ErrUnsupportedFeature) } @@ -148,7 +148,7 @@ func applyPredicate( } // LocalPath implements RepoClient.LocalPath. -func (client *localDirClient) LocalPath() (string, error) { +func (client *Client) LocalPath() (string, error) { clientPath, err := filepath.Abs(client.path) if err != nil { return "", fmt.Errorf("error during filepath.Abs: %w", err) @@ -157,7 +157,7 @@ func (client *localDirClient) LocalPath() (string, error) { } // ListFiles implements RepoClient.ListFiles. -func (client *localDirClient) ListFiles(predicate func(string) (bool, error)) ([]string, error) { +func (client *Client) ListFiles(predicate func(string) (bool, error)) ([]string, error) { client.once.Do(func() { client.files, client.errFiles = listFiles(client.path) }) @@ -175,102 +175,103 @@ func getFile(clientpath, filename string) (*os.File, error) { } // GetFileReader implements RepoClient.GetFileReader. -func (client *localDirClient) GetFileReader(filename string) (io.ReadCloser, error) { +func (client *Client) GetFileReader(filename string) (io.ReadCloser, error) { return getFile(client.path, filename) } // GetBranch implements RepoClient.GetBranch. -func (client *localDirClient) GetBranch(branch string) (*clients.BranchRef, error) { +func (client *Client) GetBranch(branch string) (*clients.BranchRef, error) { return nil, fmt.Errorf("ListBranches: %w", clients.ErrUnsupportedFeature) } // GetDefaultBranch implements RepoClient.GetDefaultBranch. -func (client *localDirClient) GetDefaultBranch() (*clients.BranchRef, error) { +func (client *Client) GetDefaultBranch() (*clients.BranchRef, error) { return nil, fmt.Errorf("GetDefaultBranch: %w", clients.ErrUnsupportedFeature) } // GetDefaultBranchName implements RepoClient.GetDefaultBranchName. -func (client *localDirClient) GetDefaultBranchName() (string, error) { +func (client *Client) GetDefaultBranchName() (string, error) { return "", fmt.Errorf("GetDefaultBranchName: %w", clients.ErrUnsupportedFeature) } // ListCommits implements RepoClient.ListCommits. -func (client *localDirClient) ListCommits() ([]clients.Commit, error) { +func (client *Client) ListCommits() ([]clients.Commit, error) { return nil, fmt.Errorf("ListCommits: %w", clients.ErrUnsupportedFeature) } // ListIssues implements RepoClient.ListIssues. -func (client *localDirClient) ListIssues() ([]clients.Issue, error) { +func (client *Client) ListIssues() ([]clients.Issue, error) { return nil, fmt.Errorf("ListIssues: %w", clients.ErrUnsupportedFeature) } // ListReleases implements RepoClient.ListReleases. -func (client *localDirClient) ListReleases() ([]clients.Release, error) { +func (client *Client) ListReleases() ([]clients.Release, error) { return nil, fmt.Errorf("ListReleases: %w", clients.ErrUnsupportedFeature) } // ListContributors implements RepoClient.ListContributors. -func (client *localDirClient) ListContributors() ([]clients.User, error) { +func (client *Client) ListContributors() ([]clients.User, error) { return nil, fmt.Errorf("ListContributors: %w", clients.ErrUnsupportedFeature) } // ListSuccessfulWorkflowRuns implements RepoClient.WorkflowRunsByFilename. -func (client *localDirClient) ListSuccessfulWorkflowRuns(filename string) ([]clients.WorkflowRun, error) { +func (client *Client) ListSuccessfulWorkflowRuns(filename string) ([]clients.WorkflowRun, error) { return nil, fmt.Errorf("ListSuccessfulWorkflowRuns: %w", clients.ErrUnsupportedFeature) } // ListCheckRunsForRef implements RepoClient.ListCheckRunsForRef. -func (client *localDirClient) ListCheckRunsForRef(ref string) ([]clients.CheckRun, error) { +func (client *Client) ListCheckRunsForRef(ref string) ([]clients.CheckRun, error) { return nil, fmt.Errorf("ListCheckRunsForRef: %w", clients.ErrUnsupportedFeature) } // ListStatuses implements RepoClient.ListStatuses. -func (client *localDirClient) ListStatuses(ref string) ([]clients.Status, error) { +func (client *Client) ListStatuses(ref string) ([]clients.Status, error) { return nil, fmt.Errorf("ListStatuses: %w", clients.ErrUnsupportedFeature) } // ListWebhooks implements RepoClient.ListWebhooks. -func (client *localDirClient) ListWebhooks() ([]clients.Webhook, error) { +func (client *Client) ListWebhooks() ([]clients.Webhook, error) { return nil, fmt.Errorf("ListWebhooks: %w", clients.ErrUnsupportedFeature) } // Search implements RepoClient.Search. -func (client *localDirClient) Search(request clients.SearchRequest) (clients.SearchResponse, error) { +func (client *Client) Search(request clients.SearchRequest) (clients.SearchResponse, error) { return clients.SearchResponse{}, fmt.Errorf("Search: %w", clients.ErrUnsupportedFeature) } // SearchCommits implements RepoClient.SearchCommits. -func (client *localDirClient) SearchCommits(request clients.SearchCommitsOptions) ([]clients.Commit, error) { +func (client *Client) SearchCommits(request clients.SearchCommitsOptions) ([]clients.Commit, error) { return nil, fmt.Errorf("Search: %w", clients.ErrUnsupportedFeature) } -func (client *localDirClient) Close() error { +func (client *Client) Close() error { return nil } // ListProgrammingLanguages implements RepoClient.ListProgrammingLanguages. // TODO: add ListProgrammingLanguages support for local directories. -func (client *localDirClient) ListProgrammingLanguages() ([]clients.Language, error) { - return nil, fmt.Errorf("ListProgrammingLanguages: %w", clients.ErrUnsupportedFeature) +func (client *Client) ListProgrammingLanguages() ([]clients.Language, error) { + // for now just return all programming languages + return []clients.Language{{Name: clients.All, NumLines: 1}}, nil } // ListLicenses implements RepoClient.ListLicenses. // TODO: add ListLicenses support for local directories. -func (client *localDirClient) ListLicenses() ([]clients.License, error) { +func (client *Client) ListLicenses() ([]clients.License, error) { return nil, fmt.Errorf("ListLicenses: %w", clients.ErrUnsupportedFeature) } -func (client *localDirClient) GetCreatedAt() (time.Time, error) { +func (client *Client) GetCreatedAt() (time.Time, error) { return time.Time{}, fmt.Errorf("GetCreatedAt: %w", clients.ErrUnsupportedFeature) } -func (client *localDirClient) GetOrgRepoClient(ctx context.Context) (clients.RepoClient, error) { +func (client *Client) GetOrgRepoClient(ctx context.Context) (clients.RepoClient, error) { return nil, fmt.Errorf("GetOrgRepoClient: %w", clients.ErrUnsupportedFeature) } // CreateLocalDirClient returns a client which implements RepoClient interface. func CreateLocalDirClient(ctx context.Context, logger *log.Logger) clients.RepoClient { - return &localDirClient{ + return &Client{ ctx: ctx, logger: logger, } diff --git a/cmd/root.go b/cmd/root.go index 39d2881518d1..23626a634bbb 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -118,9 +118,11 @@ func rootCmd(o *options.Options) error { } var requiredRequestTypes []checker.RequestType + // if local option not set add file based if o.Local != "" { requiredRequestTypes = append(requiredRequestTypes, checker.FileBased) } + // if commit option set to anything other than HEAD add commit based if !strings.EqualFold(o.Commit, clients.HeadSHA) { requiredRequestTypes = append(requiredRequestTypes, checker.CommitBased) } diff --git a/policy/policy_test.go b/policy/policy_test.go index 8d762d9bc61a..bf2050943f43 100644 --- a/policy/policy_test.go +++ b/policy/policy_test.go @@ -333,7 +333,7 @@ func TestGetEnabled(t *testing.T) { name: "request types limit enabled checks", argsChecks: []string{}, requiredRequestTypes: []checker.RequestType{checker.FileBased, checker.CommitBased}, - expectedEnabledChecks: 5, // All checks which are FileBased and CommitBased + expectedEnabledChecks: 7, // All checks which are FileBased and CommitBased expectedError: false, }, { From 57850eebd5ea20b299c10981e73bba168d444e86 Mon Sep 17 00:00:00 2001 From: Jamie Magee Date: Tue, 3 Dec 2024 07:21:56 -0800 Subject: [PATCH 08/12] :sparkles: implement `ListIssues` and `GetCreatedAt` for Azure DevOps (#4419) * :sparkles: implement `ListIssues` and `GetCreatedAt` for Azure DevOps Signed-off-by: Jamie Magee * PR comments Signed-off-by: Jamie Magee * Reset issues list on initialization Signed-off-by: Jamie Magee --------- Signed-off-by: Jamie Magee --- clients/azuredevopsrepo/audit.go | 87 ++++++++++ clients/azuredevopsrepo/audit_test.go | 89 ++++++++++ clients/azuredevopsrepo/client.go | 37 ++++- clients/azuredevopsrepo/commits.go | 58 +++++-- clients/azuredevopsrepo/work_items.go | 181 ++++++++++++++++++++ clients/azuredevopsrepo/work_items_test.go | 185 +++++++++++++++++++++ 6 files changed, 625 insertions(+), 12 deletions(-) create mode 100644 clients/azuredevopsrepo/audit.go create mode 100644 clients/azuredevopsrepo/audit_test.go create mode 100644 clients/azuredevopsrepo/work_items.go create mode 100644 clients/azuredevopsrepo/work_items_test.go diff --git a/clients/azuredevopsrepo/audit.go b/clients/azuredevopsrepo/audit.go new file mode 100644 index 000000000000..759ad98fc567 --- /dev/null +++ b/clients/azuredevopsrepo/audit.go @@ -0,0 +1,87 @@ +// Copyright 2024 OpenSSF Scorecard Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package azuredevopsrepo + +import ( + "context" + "fmt" + "sync" + "time" + + "github.com/microsoft/azure-devops-go-api/azuredevops/v7/audit" +) + +type auditHandler struct { + auditClient audit.Client + once *sync.Once + ctx context.Context + errSetup error + repourl *Repo + createdAt time.Time + queryLog fnQueryLog +} + +func (a *auditHandler) init(ctx context.Context, repourl *Repo) { + a.ctx = ctx + a.errSetup = nil + a.once = new(sync.Once) + a.repourl = repourl + a.queryLog = a.auditClient.QueryLog +} + +type ( + fnQueryLog func(ctx context.Context, args audit.QueryLogArgs) (*audit.AuditLogQueryResult, error) +) + +func (a *auditHandler) setup() error { + a.once.Do(func() { + continuationToken := "" + for { + auditLog, err := a.queryLog(a.ctx, audit.QueryLogArgs{ + ContinuationToken: &continuationToken, + }) + if err != nil { + a.errSetup = fmt.Errorf("error querying audit log: %w", err) + return + } + + // Check if Git.CreateRepo event exists for the repository + for i := range *auditLog.DecoratedAuditLogEntries { + entry := &(*auditLog.DecoratedAuditLogEntries)[i] + if *entry.ActionId == "Git.CreateRepo" && + *entry.ProjectName == a.repourl.project && + (*entry.Data)["RepoName"] == a.repourl.name { + a.createdAt = entry.Timestamp.Time + return + } + } + + if *auditLog.HasMore { + continuationToken = *auditLog.ContinuationToken + } else { + return + } + } + }) + return a.errSetup +} + +func (a *auditHandler) getRepsitoryCreatedAt() (time.Time, error) { + if err := a.setup(); err != nil { + return time.Time{}, fmt.Errorf("error during auditHandler.setup: %w", err) + } + + return a.createdAt, nil +} diff --git a/clients/azuredevopsrepo/audit_test.go b/clients/azuredevopsrepo/audit_test.go new file mode 100644 index 000000000000..72c595c120d4 --- /dev/null +++ b/clients/azuredevopsrepo/audit_test.go @@ -0,0 +1,89 @@ +// Copyright 2024 OpenSSF Scorecard Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package azuredevopsrepo + +import ( + "context" + "errors" + "sync" + "testing" + "time" + + "github.com/microsoft/azure-devops-go-api/azuredevops/v7" + "github.com/microsoft/azure-devops-go-api/azuredevops/v7/audit" +) + +func Test_auditHandler_setup(t *testing.T) { + t.Parallel() + tests := []struct { + queryLog fnQueryLog + createdAt time.Time + name string + wantErr bool + }{ + { + name: "successful setup", + queryLog: func(ctx context.Context, args audit.QueryLogArgs) (*audit.AuditLogQueryResult, error) { + return &audit.AuditLogQueryResult{ + HasMore: new(bool), + ContinuationToken: new(string), + DecoratedAuditLogEntries: &[]audit.DecoratedAuditLogEntry{ + { + ActionId: strptr("Git.CreateRepo"), + ProjectName: strptr("test-project"), + Data: &map[string]interface{}{"RepoName": "test-repo"}, + Timestamp: &azuredevops.Time{Time: time.Date(2023, time.January, 1, 0, 0, 0, 0, time.UTC)}, + }, + }, + }, nil + }, + wantErr: false, + createdAt: time.Date(2023, time.January, 1, 0, 0, 0, 0, time.UTC), + }, + { + name: "query log error", + queryLog: func(ctx context.Context, args audit.QueryLogArgs) (*audit.AuditLogQueryResult, error) { + return nil, errors.New("query log error") + }, + wantErr: true, + createdAt: time.Time{}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + handler := &auditHandler{ + once: new(sync.Once), + queryLog: tt.queryLog, + repourl: &Repo{ + project: "test-project", + name: "test-repo", + }, + } + err := handler.setup() + if (err != nil) != tt.wantErr { + t.Fatalf("setup() error = %v, wantErr %v", err, tt.wantErr) + } + if !tt.wantErr && !handler.createdAt.Equal(tt.createdAt) { + t.Errorf("setup() createdAt = %v, want %v", handler.createdAt, tt.createdAt) + } + }) + } +} + +func strptr(s string) *string { + return &s +} diff --git a/clients/azuredevopsrepo/client.go b/clients/azuredevopsrepo/client.go index 35495f18e91b..a89f6cf10900 100644 --- a/clients/azuredevopsrepo/client.go +++ b/clients/azuredevopsrepo/client.go @@ -24,7 +24,9 @@ import ( "time" "github.com/microsoft/azure-devops-go-api/azuredevops/v7" + "github.com/microsoft/azure-devops-go-api/azuredevops/v7/audit" "github.com/microsoft/azure-devops-go-api/azuredevops/v7/git" + "github.com/microsoft/azure-devops-go-api/azuredevops/v7/workitemtracking" "github.com/ossf/scorecard/v5/clients" ) @@ -40,8 +42,10 @@ type Client struct { ctx context.Context repourl *Repo repo *git.GitRepository + audit *auditHandler branches *branchesHandler commits *commitsHandler + workItems *workItemsHandler zip *zipHandler commitDepth int } @@ -81,10 +85,14 @@ func (c *Client) InitRepo(inputRepo clients.Repo, commitSHA string, commitDepth commitSHA: commitSHA, } + c.audit.init(c.ctx, c.repourl) + c.branches.init(c.ctx, c.repourl) c.commits.init(c.ctx, c.repourl, c.commitDepth) + c.workItems.init(c.ctx, c.repourl) + c.zip.init(c.ctx, c.repourl) return nil @@ -115,7 +123,16 @@ func (c *Client) GetBranch(branch string) (*clients.BranchRef, error) { } func (c *Client) GetCreatedAt() (time.Time, error) { - return time.Time{}, clients.ErrUnsupportedFeature + createdAt, err := c.audit.getRepsitoryCreatedAt() + if err != nil { + return time.Time{}, err + } + + // The audit log may not be enabled on the repository + if createdAt.IsZero() { + return c.commits.getFirstCommitCreatedAt() + } + return createdAt, nil } func (c *Client) GetDefaultBranchName() (string, error) { @@ -139,7 +156,7 @@ func (c *Client) ListCommits() ([]clients.Commit, error) { } func (c *Client) ListIssues() ([]clients.Issue, error) { - return nil, clients.ErrUnsupportedFeature + return c.workItems.listIssues() } func (c *Client) ListLicenses() ([]clients.License, error) { @@ -198,20 +215,36 @@ func CreateAzureDevOpsClientWithToken(ctx context.Context, token string, repo cl client := connection.GetClientByUrl(url) + auditClient, err := audit.NewClient(ctx, connection) + if err != nil { + return nil, fmt.Errorf("could not create azure devops audit client with error: %w", err) + } + gitClient, err := git.NewClient(ctx, connection) if err != nil { return nil, fmt.Errorf("could not create azure devops git client with error: %w", err) } + workItemsClient, err := workitemtracking.NewClient(ctx, connection) + if err != nil { + return nil, fmt.Errorf("could not create azure devops work item tracking client with error: %w", err) + } + return &Client{ ctx: ctx, azdoClient: gitClient, + audit: &auditHandler{ + auditClient: auditClient, + }, branches: &branchesHandler{ gitClient: gitClient, }, commits: &commitsHandler{ gitClient: gitClient, }, + workItems: &workItemsHandler{ + workItemsClient: workItemsClient, + }, zip: &zipHandler{ client: client, }, diff --git a/clients/azuredevopsrepo/commits.go b/clients/azuredevopsrepo/commits.go index abda5812007f..5ba597b613a4 100644 --- a/clients/azuredevopsrepo/commits.go +++ b/clients/azuredevopsrepo/commits.go @@ -19,6 +19,7 @@ import ( "errors" "fmt" "sync" + "time" "github.com/microsoft/azure-devops-go-api/azuredevops/v7/git" @@ -28,16 +29,18 @@ import ( var errMultiplePullRequests = errors.New("expected 1 pull request for commit, got multiple") type commitsHandler struct { - gitClient git.Client - ctx context.Context - errSetup error - once *sync.Once - repourl *Repo - commitsRaw *[]git.GitCommitRef - pullRequestsRaw *git.GitPullRequestQuery - getCommits fnGetCommits - getPullRequestQuery fnGetPullRequestQuery - commitDepth int + gitClient git.Client + ctx context.Context + errSetup error + once *sync.Once + repourl *Repo + commitsRaw *[]git.GitCommitRef + pullRequestsRaw *git.GitPullRequestQuery + firstCommitCreatedAt time.Time + getCommits fnGetCommits + getPullRequestQuery fnGetPullRequestQuery + getFirstCommit fnGetFirstCommit + commitDepth int } func (handler *commitsHandler) init(ctx context.Context, repourl *Repo, commitDepth int) { @@ -48,11 +51,13 @@ func (handler *commitsHandler) init(ctx context.Context, repourl *Repo, commitDe handler.commitDepth = commitDepth handler.getCommits = handler.gitClient.GetCommits handler.getPullRequestQuery = handler.gitClient.GetPullRequestQuery + handler.getFirstCommit = handler.gitClient.GetCommits } type ( fnGetCommits func(ctx context.Context, args git.GetCommitsArgs) (*[]git.GitCommitRef, error) fnGetPullRequestQuery func(ctx context.Context, args git.GetPullRequestQueryArgs) (*git.GitPullRequestQuery, error) + fnGetFirstCommit func(ctx context.Context, args git.GetCommitsArgs) (*[]git.GitCommitRef, error) ) func (handler *commitsHandler) setup() error { @@ -106,6 +111,31 @@ func (handler *commitsHandler) setup() error { return } + switch { + case len(*commits) == 0: + handler.firstCommitCreatedAt = time.Time{} + case len(*commits) < handler.commitDepth: + handler.firstCommitCreatedAt = (*commits)[len(*commits)-1].Committer.Date.Time + default: + firstCommit, err := handler.getFirstCommit(handler.ctx, git.GetCommitsArgs{ + RepositoryId: &handler.repourl.id, + SearchCriteria: &git.GitQueryCommitsCriteria{ + Top: &[]int{1}[0], + ShowOldestCommitsFirst: &[]bool{true}[0], + ItemVersion: &git.GitVersionDescriptor{ + VersionType: &git.GitVersionTypeValues.Branch, + Version: &handler.repourl.defaultBranch, + }, + }, + }) + if err != nil { + handler.errSetup = fmt.Errorf("request for first commit failed with %w", err) + return + } + + handler.firstCommitCreatedAt = (*firstCommit)[0].Committer.Date.Time + } + handler.commitsRaw = commits handler.pullRequestsRaw = pullRequests @@ -182,3 +212,11 @@ func (handler *commitsHandler) listPullRequests() (map[string]clients.PullReques return pullRequests, nil } + +func (handler *commitsHandler) getFirstCommitCreatedAt() (time.Time, error) { + if err := handler.setup(); err != nil { + return time.Time{}, fmt.Errorf("error during commitsHandler.setup: %w", err) + } + + return handler.firstCommitCreatedAt, nil +} diff --git a/clients/azuredevopsrepo/work_items.go b/clients/azuredevopsrepo/work_items.go new file mode 100644 index 000000000000..0d08d98c3c52 --- /dev/null +++ b/clients/azuredevopsrepo/work_items.go @@ -0,0 +1,181 @@ +// Copyright 2024 OpenSSF Scorecard Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package azuredevopsrepo + +import ( + "context" + "fmt" + "sync" + "time" + + "github.com/microsoft/azure-devops-go-api/azuredevops/v7/workitemtracking" + + "github.com/ossf/scorecard/v5/clients" +) + +var ( + errSystemCreatedByFieldNotMap = fmt.Errorf("error: System.CreatedBy field is not a map") + errSystemCreatedByFieldNotUniqueName = fmt.Errorf("error: System.CreatedBy field does not contain a UniqueName") + errSystemCreatedDateFieldNotString = fmt.Errorf("error: System.CreatedDate field is not a string") +) + +type ( + fnQueryWorkItems func( + ctx context.Context, + args workitemtracking.QueryByWiqlArgs, + ) (*workitemtracking.WorkItemQueryResult, error) + + fnGetWorkItems func( + ctx context.Context, + args workitemtracking.GetWorkItemsArgs, + ) (*[]workitemtracking.WorkItem, error) + + fnGetWorkItemComments func( + ctx context.Context, + args workitemtracking.GetCommentsArgs, + ) (*workitemtracking.CommentList, error) +) + +type workItemsHandler struct { + ctx context.Context + repourl *Repo + once *sync.Once + errSetup error + workItemsClient workitemtracking.Client + queryWorkItems fnQueryWorkItems + getWorkItems fnGetWorkItems + getWorkItemComments fnGetWorkItemComments + issues []clients.Issue +} + +func (w *workItemsHandler) init(ctx context.Context, repourl *Repo) { + w.ctx = ctx + w.errSetup = nil + w.once = new(sync.Once) + w.repourl = repourl + w.queryWorkItems = w.workItemsClient.QueryByWiql + w.getWorkItems = w.workItemsClient.GetWorkItems + w.getWorkItemComments = w.workItemsClient.GetComments + w.issues = nil +} + +func (w *workItemsHandler) setup() error { + w.once.Do(func() { + wiql := ` + SELECT [System.Id] + FROM WorkItems + WHERE [System.TeamProject] = @project + ORDER BY [System.Id] DESC + ` + workItems, err := w.queryWorkItems(w.ctx, workitemtracking.QueryByWiqlArgs{ + Project: &w.repourl.project, + Wiql: &workitemtracking.Wiql{ + Query: &wiql, + }, + }) + if err != nil { + w.errSetup = fmt.Errorf("error getting work items: %w", err) + return + } + + ids := make([]int, 0, len(*workItems.WorkItems)) + for _, wi := range *workItems.WorkItems { + ids = append(ids, *wi.Id) + } + + // Get details for each work item + workItemDetails, err := w.getWorkItems(w.ctx, workitemtracking.GetWorkItemsArgs{ + Ids: &ids, + }) + if err != nil { + w.errSetup = fmt.Errorf("error getting work item details: %w", err) + return + } + + w.issues = make([]clients.Issue, 0, len(*workItemDetails)) + for i := range *workItemDetails { + wi := &(*workItemDetails)[i] + + createdBy, ok := (*wi.Fields)["System.CreatedBy"].(map[string]interface{}) + if !ok { + w.errSetup = errSystemCreatedByFieldNotMap + return + } + uniqueName, ok := createdBy["uniqueName"].(string) + if !ok { + w.errSetup = errSystemCreatedByFieldNotUniqueName + return + } + createdDate, ok := (*wi.Fields)["System.CreatedDate"].(string) + if !ok { + w.errSetup = errSystemCreatedDateFieldNotString + return + } + parsedTime, err := time.Parse(time.RFC3339, createdDate) + if err != nil { + w.errSetup = fmt.Errorf("error parsing created date: %w", err) + return + } + // There is not currently an official API to get user permissions in Azure DevOps + // so we will default to RepoAssociationMember for all users. + repoAssociation := clients.RepoAssociationMember + + issue := clients.Issue{ + URI: wi.Url, + CreatedAt: &parsedTime, + Author: &clients.User{Login: uniqueName}, + AuthorAssociation: &repoAssociation, + Comments: make([]clients.IssueComment, 0), + } + + workItemComments, err := w.getWorkItemComments(w.ctx, workitemtracking.GetCommentsArgs{ + Project: &w.repourl.project, + WorkItemId: wi.Id, + }) + if err != nil { + w.errSetup = fmt.Errorf("error getting comments for work item %d: %w", *wi.Id, err) + return + } + + for i := range *workItemComments.Comments { + workItemComment := &(*workItemComments.Comments)[i] + + // There is not currently an official API to get user permissions in Azure DevOps + // so we will default to RepoAssociationMember for all users. + repoAssociation := clients.RepoAssociationMember + + comment := clients.IssueComment{ + CreatedAt: &workItemComment.CreatedDate.Time, + Author: &clients.User{Login: *workItemComment.CreatedBy.UniqueName}, + AuthorAssociation: &repoAssociation, + } + + issue.Comments = append(issue.Comments, comment) + } + + w.issues = append(w.issues, issue) + } + }) + + return w.errSetup +} + +func (w *workItemsHandler) listIssues() ([]clients.Issue, error) { + if err := w.setup(); err != nil { + return nil, fmt.Errorf("error during issuesHandler.setup: %w", err) + } + + return w.issues, nil +} diff --git a/clients/azuredevopsrepo/work_items_test.go b/clients/azuredevopsrepo/work_items_test.go new file mode 100644 index 000000000000..1ed1d3de4df4 --- /dev/null +++ b/clients/azuredevopsrepo/work_items_test.go @@ -0,0 +1,185 @@ +// Copyright 2024 OpenSSF Scorecard Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package azuredevopsrepo + +import ( + "context" + "fmt" + "reflect" + "sync" + "testing" + "time" + + "github.com/microsoft/azure-devops-go-api/azuredevops/v7" + "github.com/microsoft/azure-devops-go-api/azuredevops/v7/webapi" + "github.com/microsoft/azure-devops-go-api/azuredevops/v7/workitemtracking" + + "github.com/ossf/scorecard/v5/clients" +) + +func TestWorkItemsHandler_listIssues(t *testing.T) { + t.Parallel() + tests := []struct { + name string + wantErrStr string + mockSetup func(*workItemsHandler) + want []clients.Issue + }{ + { + name: "happy path", + mockSetup: func(w *workItemsHandler) { + workItems := &workitemtracking.WorkItemQueryResult{ + WorkItems: &[]workitemtracking.WorkItemReference{ + {Id: toPtr(1)}, + }, + } + w.queryWorkItems = func(ctx context.Context, args workitemtracking.QueryByWiqlArgs) (*workitemtracking.WorkItemQueryResult, error) { + return workItems, nil + } + + createdDate := "2024-01-01T00:00:00Z" + workItemDetails := &[]workitemtracking.WorkItem{ + { + Id: toPtr(1), + Url: toPtr("http://example.com"), + Fields: &map[string]interface{}{ + "System.CreatedDate": createdDate, + "System.CreatedBy": map[string]interface{}{ + "uniqueName": "test-user", + }, + }, + }, + } + w.getWorkItems = func(ctx context.Context, args workitemtracking.GetWorkItemsArgs) (*[]workitemtracking.WorkItem, error) { + return workItemDetails, nil + } + + commentTime := time.Date(2024, 1, 2, 0, 0, 0, 0, time.UTC) + comments := &workitemtracking.CommentList{ + Comments: &[]workitemtracking.Comment{ + {CreatedDate: &azuredevops.Time{Time: commentTime}, CreatedBy: &webapi.IdentityRef{UniqueName: toPtr("test-user")}}, + }, + } + w.getWorkItemComments = func(ctx context.Context, args workitemtracking.GetCommentsArgs) (*workitemtracking.CommentList, error) { + return comments, nil + } + }, + want: []clients.Issue{ + { + URI: toPtr("http://example.com"), + CreatedAt: toPtr(time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)), + Author: &clients.User{Login: "test-user"}, + AuthorAssociation: toPtr(clients.RepoAssociationMember), + Comments: []clients.IssueComment{ + { + CreatedAt: toPtr(time.Date(2024, 1, 2, 0, 0, 0, 0, time.UTC)), + Author: &clients.User{Login: "test-user"}, + AuthorAssociation: toPtr(clients.RepoAssociationMember), + }, + }, + }, + }, + }, + { + name: "query work items error", + mockSetup: func(w *workItemsHandler) { + w.queryWorkItems = func(ctx context.Context, args workitemtracking.QueryByWiqlArgs) (*workitemtracking.WorkItemQueryResult, error) { + return nil, fmt.Errorf("query error") + } + }, + wantErrStr: "error during issuesHandler.setup: error getting work items: query error", + }, + { + name: "get work items error", + mockSetup: func(w *workItemsHandler) { + workItems := &workitemtracking.WorkItemQueryResult{ + WorkItems: &[]workitemtracking.WorkItemReference{ + {Id: toPtr(1)}, + }, + } + w.queryWorkItems = func(ctx context.Context, args workitemtracking.QueryByWiqlArgs) (*workitemtracking.WorkItemQueryResult, error) { + return workItems, nil + } + w.getWorkItems = func(ctx context.Context, args workitemtracking.GetWorkItemsArgs) (*[]workitemtracking.WorkItem, error) { + return nil, fmt.Errorf("get items error") + } + }, + wantErrStr: "error during issuesHandler.setup: error getting work item details: get items error", + }, + { + name: "get comments error", + mockSetup: func(w *workItemsHandler) { + workItems := &workitemtracking.WorkItemQueryResult{ + WorkItems: &[]workitemtracking.WorkItemReference{ + {Id: toPtr(1)}, + }, + } + w.queryWorkItems = func(ctx context.Context, args workitemtracking.QueryByWiqlArgs) (*workitemtracking.WorkItemQueryResult, error) { + return workItems, nil + } + createdDate := "2024-01-01T00:00:00Z" + workItemDetails := &[]workitemtracking.WorkItem{ + { + Id: toPtr(1), + Url: toPtr("http://example.com"), + Fields: &map[string]interface{}{ + "System.CreatedDate": createdDate, + "System.CreatedBy": map[string]interface{}{ + "uniqueName": "test-user", + }, + }, + }, + } + w.getWorkItems = func(ctx context.Context, args workitemtracking.GetWorkItemsArgs) (*[]workitemtracking.WorkItem, error) { + return workItemDetails, nil + } + w.getWorkItemComments = func(ctx context.Context, args workitemtracking.GetCommentsArgs) (*workitemtracking.CommentList, error) { + return nil, fmt.Errorf("comments error") + } + }, + wantErrStr: "error during issuesHandler.setup: error getting comments for work item 1: comments error", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + w := &workItemsHandler{ + ctx: context.Background(), + once: new(sync.Once), + repourl: &Repo{project: "test-project"}, + } + tt.mockSetup(w) + + got, err := w.listIssues() + if tt.wantErrStr != "" { + if err == nil || err.Error() != tt.wantErrStr { + t.Errorf("listIssues() error = %v, wantErr %v", err, tt.wantErrStr) + } + return + } + if err != nil { + t.Errorf("listIssues() unexpected error: %v", err) + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("listIssues() = %v, want %v", got, tt.want) + } + }) + } +} + +func toPtr[T any](v T) *T { + return &v +} From a7dac3548def43f998d690fbb56e2a1614702c6b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Dec 2024 16:46:59 +0000 Subject: [PATCH 09/12] :seedling: Bump google.golang.org/protobuf from 1.35.1 to 1.35.2 (#4426) --- go.mod | 2 +- go.sum | 4 ++-- tools/go.mod | 2 +- tools/go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 2f667e599118..1b7ddecc2ce3 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,7 @@ require ( golang.org/x/text v0.19.0 golang.org/x/tools v0.26.0 // indirect google.golang.org/genproto v0.0.0-20241015192408-796eee8c2d53 // indirect - google.golang.org/protobuf v1.35.1 + google.golang.org/protobuf v1.35.2 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 mvdan.cc/sh/v3 v3.10.0 diff --git a/go.sum b/go.sum index 419539dfbb55..3fb4fb9b6d39 100644 --- a/go.sum +++ b/go.sum @@ -1181,8 +1181,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= -google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= +google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/tools/go.mod b/tools/go.mod index bebb19355309..e90a4289a933 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -9,7 +9,7 @@ require ( github.com/google/ko v0.16.0 github.com/goreleaser/goreleaser/v2 v2.3.2 github.com/onsi/ginkgo/v2 v2.20.2 - google.golang.org/protobuf v1.35.1 + google.golang.org/protobuf v1.35.2 ) require ( diff --git a/tools/go.sum b/tools/go.sum index f772d25a6ee5..9a1dad32daf9 100644 --- a/tools/go.sum +++ b/tools/go.sum @@ -1369,8 +1369,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= -google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= +google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From bf3432df93bf2119aa791d1ecf34222f3483be9e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Dec 2024 17:09:45 +0000 Subject: [PATCH 10/12] :seedling: Bump github.com/onsi/ginkgo/v2 from 2.20.2 to 2.22.0 (#4429) --- go.mod | 4 ++-- go.sum | 8 ++++---- tools/go.mod | 16 ++++++++-------- tools/go.sum | 32 ++++++++++++++++---------------- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/go.mod b/go.mod index 1b7ddecc2ce3..913e7b960d7d 100644 --- a/go.mod +++ b/go.mod @@ -44,7 +44,7 @@ require ( github.com/google/go-github/v53 v53.2.0 github.com/google/osv-scanner v1.9.1 github.com/mcuadros/go-jsonschema-generator v0.0.0-20200330054847-ba7a369d4303 - github.com/onsi/ginkgo/v2 v2.20.2 + github.com/onsi/ginkgo/v2 v2.22.0 github.com/otiai10/copy v1.14.0 sigs.k8s.io/release-utils v0.8.4 ) @@ -83,7 +83,7 @@ require ( github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-github/v62 v62.0.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 // indirect + github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db // indirect github.com/google/s2a-go v0.1.8 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-retryablehttp v0.7.7 // indirect diff --git a/go.sum b/go.sum index 3fb4fb9b6d39..b73a91c6a4af 100644 --- a/go.sum +++ b/go.sum @@ -414,8 +414,8 @@ github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OI github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 h1:5iH8iuqE5apketRbSFBy+X1V0o+l+8NF1avt4HWl7cA= -github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM= github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA= @@ -606,8 +606,8 @@ github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+ github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= -github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag= +github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= +github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= diff --git a/tools/go.mod b/tools/go.mod index e90a4289a933..4ddcfeeb107b 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -8,7 +8,7 @@ require ( github.com/google/addlicense v1.1.1 github.com/google/ko v0.16.0 github.com/goreleaser/goreleaser/v2 v2.3.2 - github.com/onsi/ginkgo/v2 v2.20.2 + github.com/onsi/ginkgo/v2 v2.22.0 google.golang.org/protobuf v1.35.2 ) @@ -216,7 +216,7 @@ require ( github.com/google/go-containerregistry v0.20.2 // indirect github.com/google/go-github/v65 v65.0.0 // indirect github.com/google/go-querystring v1.1.0 // indirect - github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 // indirect + github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db // indirect github.com/google/rpmpack v0.6.1-0.20240329070804-c2247cbb881a // indirect github.com/google/s2a-go v0.1.8 // indirect github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2 // indirect @@ -420,18 +420,18 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect gocloud.dev v0.39.0 // indirect - golang.org/x/crypto v0.27.0 // indirect + golang.org/x/crypto v0.28.0 // indirect golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e // indirect golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f // indirect golang.org/x/mod v0.21.0 // indirect - golang.org/x/net v0.29.0 // indirect + golang.org/x/net v0.30.0 // indirect golang.org/x/oauth2 v0.23.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/term v0.24.0 // indirect - golang.org/x/text v0.18.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/term v0.25.0 // indirect + golang.org/x/text v0.19.0 // indirect golang.org/x/time v0.6.0 // indirect - golang.org/x/tools v0.25.0 // indirect + golang.org/x/tools v0.26.0 // indirect golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect google.golang.org/api v0.196.0 // indirect google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1 // indirect diff --git a/tools/go.sum b/tools/go.sum index 9a1dad32daf9..e9e3ee9284d5 100644 --- a/tools/go.sum +++ b/tools/go.sum @@ -542,8 +542,8 @@ github.com/google/ko v0.16.0/go.mod h1:B7EYCmD87kqCYrrHvtSJEe7h3N8hstqeWvGRyDG8S github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc= github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 h1:5iH8iuqE5apketRbSFBy+X1V0o+l+8NF1avt4HWl7cA= -github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/rpmpack v0.6.1-0.20240329070804-c2247cbb881a h1:JJBdjSfqSy3mnDT0940ASQFghwcZ4y4cb6ttjAoXqwE= github.com/google/rpmpack v0.6.1-0.20240329070804-c2247cbb881a/go.mod h1:uqVAUVQLq8UY2hCDfmJ/+rtO3aw7qyhc90rCVEabEfI= @@ -826,8 +826,8 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= -github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag= +github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= +github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= @@ -1155,8 +1155,8 @@ golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58 golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e h1:I88y4caeGeuDQxgdoFPUq097j7kNfw6uvuiNxUBfcBk= golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= @@ -1210,8 +1210,8 @@ golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= @@ -1265,8 +1265,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1277,8 +1277,8 @@ golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= -golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= -golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= +golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= +golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -1291,8 +1291,8 @@ golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1330,8 +1330,8 @@ golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= -golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= -golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= +golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= +golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 86f46b1eb2c04113855ca473583fe383a5871a97 Mon Sep 17 00:00:00 2001 From: Jamie Magee Date: Tue, 3 Dec 2024 14:05:47 -0800 Subject: [PATCH 11/12] =?UTF-8?q?=E2=9C=A8=20implement=20`Search`=20for=20?= =?UTF-8?q?Azure=20DevOps=20(#4428)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * :sparkles: implement `Search` for Azure DevOps Signed-off-by: Jamie Magee * Add E2E search test for Azure DevOps Signed-off-by: Jamie Magee * PR comments Signed-off-by: Jamie Magee * PR comments Signed-off-by: Jamie Magee --------- Signed-off-by: Jamie Magee --- Makefile | 4 + .../azure_devops_suite_test.go | 35 +++ clients/azuredevopsrepo/client.go | 14 +- clients/azuredevopsrepo/search.go | 105 +++++++++ clients/azuredevopsrepo/search_e2e_test.go | 48 +++++ clients/azuredevopsrepo/search_test.go | 203 ++++++++++++++++++ 6 files changed, 408 insertions(+), 1 deletion(-) create mode 100644 clients/azuredevopsrepo/azure_devops_suite_test.go create mode 100644 clients/azuredevopsrepo/search.go create mode 100644 clients/azuredevopsrepo/search_e2e_test.go create mode 100644 clients/azuredevopsrepo/search_test.go diff --git a/Makefile b/Makefile index 18bd66ba1864..c14bdae16fe9 100644 --- a/Makefile +++ b/Makefile @@ -356,6 +356,10 @@ e2e-gitlab: ## Runs e2e tests for GitLab only. TOKEN_TYPE is not used (since the e2e-gitlab: build-scorecard | $(GINKGO) TEST_GITLAB_EXTERNAL=1 TOKEN_TYPE="PAT" $(GINKGO) --race -p -vv -coverprofile=e2e-coverage.out --keep-separate-coverprofiles --focus ".*GitLab" ./... +e2e-azure-devops-token: ## Runs e2e tests that require a AZURE_DEVOPS_AUTH_TOKEN +e2e-azure-devops-token: build-scorecard check-env-gitlab | $(GINKGO) + TEST_AZURE_DEVOPS_EXTERNAL=1 TOKEN_TYPE="GITLAB_PAT" $(GINKGO) --race -p -vv -coverprofile=e2e-coverage.out --keep-separate-coverprofiles --focus '.*Azure DevOps' ./... + e2e-attestor: ## Runs e2e tests for scorecard-attestor cd attestor/e2e; go test -covermode=atomic -coverprofile=e2e-coverage.out; cd ../.. diff --git a/clients/azuredevopsrepo/azure_devops_suite_test.go b/clients/azuredevopsrepo/azure_devops_suite_test.go new file mode 100644 index 000000000000..a04638bc529a --- /dev/null +++ b/clients/azuredevopsrepo/azure_devops_suite_test.go @@ -0,0 +1,35 @@ +// Copyright 2024 OpenSSF Scorecard Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package azuredevopsrepo + +import ( + "os" + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestAzureDevOpsRepoE2E(t *testing.T) { + if val, exists := os.LookupEnv("SKIP_GINKGO"); exists && val == "1" { + t.Skip() + } + if val, exists := os.LookupEnv("TEST_AZURE_DEVOPS_EXTERNAL"); !exists || val != "1" { + t.Skip() + } + t.Parallel() + RegisterFailHandler(Fail) + RunSpecs(t, "Azure DevOps Repo Suite") +} diff --git a/clients/azuredevopsrepo/client.go b/clients/azuredevopsrepo/client.go index a89f6cf10900..17f5e06fdc00 100644 --- a/clients/azuredevopsrepo/client.go +++ b/clients/azuredevopsrepo/client.go @@ -26,6 +26,7 @@ import ( "github.com/microsoft/azure-devops-go-api/azuredevops/v7" "github.com/microsoft/azure-devops-go-api/azuredevops/v7/audit" "github.com/microsoft/azure-devops-go-api/azuredevops/v7/git" + "github.com/microsoft/azure-devops-go-api/azuredevops/v7/search" "github.com/microsoft/azure-devops-go-api/azuredevops/v7/workitemtracking" "github.com/ossf/scorecard/v5/clients" @@ -45,6 +46,7 @@ type Client struct { audit *auditHandler branches *branchesHandler commits *commitsHandler + search *searchHandler workItems *workItemsHandler zip *zipHandler commitDepth int @@ -91,6 +93,8 @@ func (c *Client) InitRepo(inputRepo clients.Repo, commitSHA string, commitDepth c.commits.init(c.ctx, c.repourl, c.commitDepth) + c.search.init(c.ctx, c.repourl) + c.workItems.init(c.ctx, c.repourl) c.zip.init(c.ctx, c.repourl) @@ -192,7 +196,7 @@ func (c *Client) ListProgrammingLanguages() ([]clients.Language, error) { } func (c *Client) Search(request clients.SearchRequest) (clients.SearchResponse, error) { - return clients.SearchResponse{}, clients.ErrUnsupportedFeature + return c.search.search(request) } func (c *Client) SearchCommits(request clients.SearchCommitsOptions) ([]clients.Commit, error) { @@ -225,6 +229,11 @@ func CreateAzureDevOpsClientWithToken(ctx context.Context, token string, repo cl return nil, fmt.Errorf("could not create azure devops git client with error: %w", err) } + searchClient, err := search.NewClient(ctx, connection) + if err != nil { + return nil, fmt.Errorf("could not create azure devops search client with error: %w", err) + } + workItemsClient, err := workitemtracking.NewClient(ctx, connection) if err != nil { return nil, fmt.Errorf("could not create azure devops work item tracking client with error: %w", err) @@ -242,6 +251,9 @@ func CreateAzureDevOpsClientWithToken(ctx context.Context, token string, repo cl commits: &commitsHandler{ gitClient: gitClient, }, + search: &searchHandler{ + searchClient: searchClient, + }, workItems: &workItemsHandler{ workItemsClient: workItemsClient, }, diff --git a/clients/azuredevopsrepo/search.go b/clients/azuredevopsrepo/search.go new file mode 100644 index 000000000000..06c2cf364246 --- /dev/null +++ b/clients/azuredevopsrepo/search.go @@ -0,0 +1,105 @@ +// Copyright 2024 OpenSSF Scorecard Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package azuredevopsrepo + +import ( + "context" + "errors" + "fmt" + "strings" + "sync" + + "github.com/microsoft/azure-devops-go-api/azuredevops/v7/search" + + "github.com/ossf/scorecard/v5/clients" +) + +var errEmptyQuery = errors.New("search query is empty") + +type searchHandler struct { + searchClient search.Client + once *sync.Once + ctx context.Context + repourl *Repo + searchCode fnSearchCode +} + +func (s *searchHandler) init(ctx context.Context, repourl *Repo) { + s.ctx = ctx + s.once = new(sync.Once) + s.repourl = repourl + s.searchCode = s.searchClient.FetchCodeSearchResults +} + +type ( + fnSearchCode func(ctx context.Context, args search.FetchCodeSearchResultsArgs) (*search.CodeSearchResponse, error) +) + +func (s *searchHandler) search(request clients.SearchRequest) (clients.SearchResponse, error) { + filters, query, err := s.buildFilters(request) + if err != nil { + return clients.SearchResponse{}, fmt.Errorf("handler.buildQuery: %w", err) + } + + searchResultsPageSize := 1000 + args := search.FetchCodeSearchResultsArgs{ + Request: &search.CodeSearchRequest{ + Filters: &filters, + SearchText: &query, + Top: &searchResultsPageSize, + }, + } + searchResults, err := s.searchCode(s.ctx, args) + if err != nil { + return clients.SearchResponse{}, fmt.Errorf("FetchCodeSearchResults: %w", err) + } + + return searchResponseFrom(searchResults), nil +} + +func (s *searchHandler) buildFilters(request clients.SearchRequest) (map[string][]string, string, error) { + filters := make(map[string][]string) + query := strings.Builder{} + if request.Query == "" { + return filters, query.String(), errEmptyQuery + } + query.WriteString(request.Query) + query.WriteString(" ") + + filters["Project"] = []string{s.repourl.project} + filters["Repository"] = []string{s.repourl.name} + + if request.Path != "" { + filters["Path"] = []string{request.Path} + } + if request.Filename != "" { + query.WriteString(fmt.Sprintf("file:%s", request.Filename)) + } + + return filters, query.String(), nil +} + +func searchResponseFrom(searchResults *search.CodeSearchResponse) clients.SearchResponse { + var results []clients.SearchResult + for _, result := range *searchResults.Results { + results = append(results, clients.SearchResult{ + Path: *result.Path, + }) + } + return clients.SearchResponse{ + Results: results, + Hits: *searchResults.Count, + } +} diff --git a/clients/azuredevopsrepo/search_e2e_test.go b/clients/azuredevopsrepo/search_e2e_test.go new file mode 100644 index 000000000000..cefadf961675 --- /dev/null +++ b/clients/azuredevopsrepo/search_e2e_test.go @@ -0,0 +1,48 @@ +// Copyright 2024 OpenSSF Scorecard Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package azuredevopsrepo + +import ( + "context" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/ossf/scorecard/v5/clients" +) + +var _ = Describe("E2E TEST: azuredevopsrepo.searchHandler", func() { + Context("Search - Azure DevOps", func() { + It("Should return search results", func() { + repo, err := MakeAzureDevOpsRepo("https://dev.azure.com/jamiemagee/jamiemagee/_git/scorecard") + Expect(err).Should(BeNil()) + + repoClient, err := CreateAzureDevOpsClient(context.Background(), repo) + Expect(err).Should(BeNil()) + + err = repoClient.InitRepo(repo, clients.HeadSHA, 0) + Expect(err).Should(BeNil()) + + request := clients.SearchRequest{ + Query: "scorecard", + Filename: "README.md", + } + results, err := repoClient.Search(request) + Expect(err).Should(BeNil()) + Expect(results.Hits).Should(BeNumerically(">", 0)) + Expect(len(results.Results)).Should(BeNumerically(">", 0)) + }) + }) +}) diff --git a/clients/azuredevopsrepo/search_test.go b/clients/azuredevopsrepo/search_test.go new file mode 100644 index 000000000000..f2f637ec2b52 --- /dev/null +++ b/clients/azuredevopsrepo/search_test.go @@ -0,0 +1,203 @@ +// Copyright 2024 OpenSSF Scorecard Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package azuredevopsrepo + +import ( + "context" + "errors" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/microsoft/azure-devops-go-api/azuredevops/v7/search" + + "github.com/ossf/scorecard/v5/clients" +) + +func Test_buildFilters(t *testing.T) { + t.Parallel() + tests := []struct { + expectedFilters map[string][]string + repourl *Repo + request clients.SearchRequest + expectedErr error + expectedQuery string + name string + }{ + { + name: "empty query", + request: clients.SearchRequest{ + Query: "", + }, + repourl: &Repo{ + project: "project", + name: "repo", + }, + expectedFilters: make(map[string][]string), + expectedQuery: "", + expectedErr: errEmptyQuery, + }, + { + name: "query only", + request: clients.SearchRequest{ + Query: "query", + }, + repourl: &Repo{ + project: "project", + name: "repo", + }, + expectedFilters: map[string][]string{ + "Project": {"project"}, + "Repository": {"repo"}, + }, + expectedQuery: "query ", + expectedErr: nil, + }, + { + name: "query and path", + request: clients.SearchRequest{ + Query: "query", + Path: "path", + }, + repourl: &Repo{ + project: "project", + name: "repo", + }, + expectedFilters: map[string][]string{ + "Project": {"project"}, + "Repository": {"repo"}, + "Path": {"path"}, + }, + expectedQuery: "query ", + expectedErr: nil, + }, + { + name: "query and filename", + request: clients.SearchRequest{ + Query: "query", + Filename: "filename", + }, + repourl: &Repo{ + project: "project", + name: "repo", + }, + expectedFilters: map[string][]string{ + "Project": {"project"}, + "Repository": {"repo"}, + }, + expectedQuery: "query file:filename", + expectedErr: nil, + }, + { + name: "query, path, and filename", + request: clients.SearchRequest{ + Query: "query", + Path: "path", + Filename: "filename", + }, + repourl: &Repo{ + project: "project", + name: "repo", + }, + expectedFilters: map[string][]string{ + "Project": {"project"}, + "Repository": {"repo"}, + "Path": {"path"}, + }, + expectedQuery: "query file:filename", + expectedErr: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + s := searchHandler{ + repourl: tt.repourl, + } + filters, query, err := s.buildFilters(tt.request) + if tt.expectedErr != nil && !errors.Is(err, tt.expectedErr) { + t.Fatalf("buildFilters() error = %v, ExpectedErr %v", err, tt.expectedErr) + } + if query != tt.expectedQuery { + t.Errorf("buildFilters() query = %v, ExpectedQuery %v", query, tt.expectedQuery) + } + if diff := cmp.Diff(filters, tt.expectedFilters); diff != "" { + t.Errorf("buildFilters() mismatch (-want +got):\n%s", diff) + } + }) + } +} + +func Test_search(t *testing.T) { + t.Parallel() + tests := []struct { + name string + request clients.SearchRequest + searchCode func(ctx context.Context, args search.FetchCodeSearchResultsArgs) (*search.CodeSearchResponse, error) + wantResults []clients.SearchResult + wantHits int + wantErr bool + }{ + { + name: "empty query", + request: clients.SearchRequest{ + Query: "", + }, + searchCode: func(ctx context.Context, args search.FetchCodeSearchResultsArgs) (*search.CodeSearchResponse, error) { + return &search.CodeSearchResponse{}, nil + }, + wantErr: true, + }, + { + name: "valid query", + request: clients.SearchRequest{ + Query: "query", + }, + searchCode: func(ctx context.Context, args search.FetchCodeSearchResultsArgs) (*search.CodeSearchResponse, error) { + return &search.CodeSearchResponse{ + Count: toPtr(1), + Results: &[]search.CodeResult{{Path: strptr("path")}}, + }, nil + }, + wantResults: []clients.SearchResult{{Path: "path"}}, + wantHits: 1, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + s := searchHandler{ + searchCode: tt.searchCode, + repourl: &Repo{ + project: "project", + name: "repo", + }, + } + + got, err := s.search(tt.request) + if (err != nil) != tt.wantErr { + t.Errorf("search() error = %v, wantErr %v", err, tt.wantErr) + return + } + if diff := cmp.Diff(got.Results, tt.wantResults); diff != "" { + t.Errorf("search() mismatch (-want +got):\n%s", diff) + } + if got.Hits != tt.wantHits { + t.Errorf("search() gotHits = %v, want %v", got.Hits, tt.wantHits) + } + }) + } +} From e94f36d3c45a10a094784a472f101310686f0c54 Mon Sep 17 00:00:00 2001 From: Jamie Magee Date: Wed, 4 Dec 2024 12:16:18 -0800 Subject: [PATCH 12/12] sparkles: add `ListProgrammingLanguages` for Azure DevOps (#4432) * sparkles: add `ListProgrammingLanguages` for Azure DevOps Signed-off-by: Jamie Magee * Handle both types of zip file Signed-off-by: Jamie Magee * gci Signed-off-by: Jamie Magee * PR comments Signed-off-by: Jamie Magee --------- Signed-off-by: Jamie Magee --- clients/azuredevopsrepo/client.go | 14 ++- clients/azuredevopsrepo/languages.go | 97 ++++++++++++++++ clients/azuredevopsrepo/languages_test.go | 128 ++++++++++++++++++++++ clients/azuredevopsrepo/zip.go | 8 +- 4 files changed, 243 insertions(+), 4 deletions(-) create mode 100644 clients/azuredevopsrepo/languages.go create mode 100644 clients/azuredevopsrepo/languages_test.go diff --git a/clients/azuredevopsrepo/client.go b/clients/azuredevopsrepo/client.go index 17f5e06fdc00..5c57f782452f 100644 --- a/clients/azuredevopsrepo/client.go +++ b/clients/azuredevopsrepo/client.go @@ -26,6 +26,7 @@ import ( "github.com/microsoft/azure-devops-go-api/azuredevops/v7" "github.com/microsoft/azure-devops-go-api/azuredevops/v7/audit" "github.com/microsoft/azure-devops-go-api/azuredevops/v7/git" + "github.com/microsoft/azure-devops-go-api/azuredevops/v7/projectanalysis" "github.com/microsoft/azure-devops-go-api/azuredevops/v7/search" "github.com/microsoft/azure-devops-go-api/azuredevops/v7/workitemtracking" @@ -46,6 +47,7 @@ type Client struct { audit *auditHandler branches *branchesHandler commits *commitsHandler + languages *languagesHandler search *searchHandler workItems *workItemsHandler zip *zipHandler @@ -93,6 +95,8 @@ func (c *Client) InitRepo(inputRepo clients.Repo, commitSHA string, commitDepth c.commits.init(c.ctx, c.repourl, c.commitDepth) + c.languages.init(c.ctx, c.repourl) + c.search.init(c.ctx, c.repourl) c.workItems.init(c.ctx, c.repourl) @@ -192,7 +196,7 @@ func (c *Client) ListWebhooks() ([]clients.Webhook, error) { } func (c *Client) ListProgrammingLanguages() ([]clients.Language, error) { - return nil, clients.ErrUnsupportedFeature + return c.languages.listProgrammingLanguages() } func (c *Client) Search(request clients.SearchRequest) (clients.SearchResponse, error) { @@ -229,6 +233,11 @@ func CreateAzureDevOpsClientWithToken(ctx context.Context, token string, repo cl return nil, fmt.Errorf("could not create azure devops git client with error: %w", err) } + projectAnalysisClient, err := projectanalysis.NewClient(ctx, connection) + if err != nil { + return nil, fmt.Errorf("could not create azure devops project analysis client with error: %w", err) + } + searchClient, err := search.NewClient(ctx, connection) if err != nil { return nil, fmt.Errorf("could not create azure devops search client with error: %w", err) @@ -251,6 +260,9 @@ func CreateAzureDevOpsClientWithToken(ctx context.Context, token string, repo cl commits: &commitsHandler{ gitClient: gitClient, }, + languages: &languagesHandler{ + projectAnalysisClient: projectAnalysisClient, + }, search: &searchHandler{ searchClient: searchClient, }, diff --git a/clients/azuredevopsrepo/languages.go b/clients/azuredevopsrepo/languages.go new file mode 100644 index 000000000000..36b7b4ae5a80 --- /dev/null +++ b/clients/azuredevopsrepo/languages.go @@ -0,0 +1,97 @@ +// Copyright 2024 OpenSSF Scorecard Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package azuredevopsrepo + +import ( + "context" + "log" + "sync" + + "github.com/microsoft/azure-devops-go-api/azuredevops/v7/projectanalysis" + + "github.com/ossf/scorecard/v5/clients" +) + +type languagesHandler struct { + ctx context.Context + once *sync.Once + repourl *Repo + projectAnalysisClient projectanalysis.Client + projectAnalysis fnGetProjectLanguageAnalytics + errSetup error + languages []clients.Language +} + +func (l *languagesHandler) init(ctx context.Context, repourl *Repo) { + l.ctx = ctx + l.once = new(sync.Once) + l.repourl = repourl + l.languages = []clients.Language{} + l.projectAnalysis = l.projectAnalysisClient.GetProjectLanguageAnalytics + l.errSetup = nil +} + +type ( + fnGetProjectLanguageAnalytics func( + ctx context.Context, + args projectanalysis.GetProjectLanguageAnalyticsArgs, + ) (*projectanalysis.ProjectLanguageAnalytics, error) +) + +func (l *languagesHandler) setup() error { + l.once.Do(func() { + args := projectanalysis.GetProjectLanguageAnalyticsArgs{ + Project: &l.repourl.project, + } + res, err := l.projectAnalysis(l.ctx, args) + if err != nil { + l.errSetup = err + return + } + + if res.ResultPhase != &projectanalysis.ResultPhaseValues.Full { + log.Println("Project language analytics not ready yet. Results may be incomplete.") + } + + for _, repo := range *res.RepositoryLanguageAnalytics { + if repo.Id.String() != l.repourl.id { + continue + } + + // TODO: Find the number of lines in the repo and multiply the value of each language by that number. + for _, language := range *repo.LanguageBreakdown { + percentage := 0 + if language.LanguagePercentage != nil { + percentage = int(*language.LanguagePercentage) + } + l.languages = append(l.languages, + clients.Language{ + Name: clients.LanguageName(*language.Name), + NumLines: percentage, + }, + ) + } + } + }) + return l.errSetup +} + +func (l *languagesHandler) listProgrammingLanguages() ([]clients.Language, error) { + if err := l.setup(); err != nil { + return nil, err + } + + return l.languages, nil +} diff --git a/clients/azuredevopsrepo/languages_test.go b/clients/azuredevopsrepo/languages_test.go new file mode 100644 index 000000000000..ec618e924c29 --- /dev/null +++ b/clients/azuredevopsrepo/languages_test.go @@ -0,0 +1,128 @@ +// Copyright 2024 OpenSSF Scorecard Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package azuredevopsrepo + +import ( + "context" + "reflect" + "sync" + "testing" + + "github.com/google/uuid" + "github.com/microsoft/azure-devops-go-api/azuredevops/v7/projectanalysis" + + "github.com/ossf/scorecard/v5/clients" +) + +func Test_listProgrammingLanguages(t *testing.T) { + t.Parallel() + tests := []struct { + name string + projectAnalysis func(ctx context.Context, args projectanalysis.GetProjectLanguageAnalyticsArgs) (*projectanalysis.ProjectLanguageAnalytics, error) + want []clients.Language + wantErr bool + }{ + { + name: "empty response", + projectAnalysis: func(ctx context.Context, args projectanalysis.GetProjectLanguageAnalyticsArgs) (*projectanalysis.ProjectLanguageAnalytics, error) { + return &projectanalysis.ProjectLanguageAnalytics{ + RepositoryLanguageAnalytics: &[]projectanalysis.RepositoryLanguageAnalytics{}, + }, nil + }, + want: []clients.Language(nil), + wantErr: false, + }, + { + name: "single response", + projectAnalysis: func(ctx context.Context, args projectanalysis.GetProjectLanguageAnalyticsArgs) (*projectanalysis.ProjectLanguageAnalytics, error) { + return &projectanalysis.ProjectLanguageAnalytics{ + RepositoryLanguageAnalytics: &[]projectanalysis.RepositoryLanguageAnalytics{ + { + Id: toPtr(uuid.Nil), + LanguageBreakdown: &[]projectanalysis.LanguageStatistics{ + { + Name: toPtr("test"), + LanguagePercentage: toPtr(float64(100)), + }, + }, + }, + }, + }, nil + }, + want: []clients.Language{ + { + Name: "test", + NumLines: 100, + }, + }, + wantErr: false, + }, + { + name: "multiple response", + projectAnalysis: func(ctx context.Context, args projectanalysis.GetProjectLanguageAnalyticsArgs) (*projectanalysis.ProjectLanguageAnalytics, error) { + return &projectanalysis.ProjectLanguageAnalytics{ + RepositoryLanguageAnalytics: &[]projectanalysis.RepositoryLanguageAnalytics{ + { + Id: toPtr(uuid.Nil), + LanguageBreakdown: &[]projectanalysis.LanguageStatistics{ + { + Name: toPtr("test1"), + LanguagePercentage: toPtr(float64(50)), + }, + { + Name: toPtr("test2"), + LanguagePercentage: toPtr(float64(50)), + }, + }, + }, + }, + }, nil + }, + want: []clients.Language{ + { + Name: "test1", + NumLines: 50, + }, + { + Name: "test2", + NumLines: 50, + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + l := &languagesHandler{ + once: new(sync.Once), + ctx: context.Background(), + repourl: &Repo{ + id: uuid.Nil.String(), + project: "project", + }, + projectAnalysis: tt.projectAnalysis, + } + got, err := l.listProgrammingLanguages() + if (err != nil) != tt.wantErr { + t.Errorf("listProgrammingLanguages() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("listProgrammingLanguages() got = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/clients/azuredevopsrepo/zip.go b/clients/azuredevopsrepo/zip.go index 6ac179ffe302..37bc2fa173d8 100644 --- a/clients/azuredevopsrepo/zip.go +++ b/clients/azuredevopsrepo/zip.go @@ -173,10 +173,12 @@ func (z *zipHandler) extractZip() error { if !strings.HasPrefix(filepath.Clean(filenamepath), destinationPrefix) { return errInvalidFilePath } + + if err := os.MkdirAll(filepath.Dir(filenamepath), 0o755); err != nil { + return fmt.Errorf("error during os.MkdirAll: %w", err) + } + if file.FileInfo().IsDir() { - if err := os.MkdirAll(filenamepath, 0o755); err != nil { - return fmt.Errorf("error during os.MkdirAll: %w", err) - } continue }