diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml index 1f1820729..a49c20b85 100644 --- a/.github/workflows/auto-merge.yml +++ b/.github/workflows/auto-merge.yml @@ -1,43 +1,15 @@ name: Dependabot auto-merge -on: pull_request permissions: - contents: write - pull-requests: write + contents: read + +on: + pull_request: jobs: dependabot: - runs-on: ubuntu-latest - if: github.event.pull_request.user.login == 'dependabot[bot]' - steps: - - name: Dependabot metadata - id: metadata - uses: dependabot/fetch-metadata@v2 - - - name: Auto-approve all dependabot PRs - run: gh pr review --approve "$PR_URL" - env: - PR_URL: ${{github.event.pull_request.html_url}} - GH_TOKEN: ${{secrets.GITHUB_TOKEN}} - - - name: Auto-merge dependabot PRs for development dependencies - if: contains(steps.metadata.outputs.dependency-group, 'development-dependencies') - run: gh pr merge --auto --rebase "$PR_URL" - env: - PR_URL: ${{github.event.pull_request.html_url}} - GH_TOKEN: ${{secrets.GITHUB_TOKEN}} - - - name: Auto-merge dependabot PRs for go-openapi patches - if: contains(steps.metadata.outputs.dependency-group, 'go-openapi-dependencies') && (steps.metadata.outputs.update-type == 'version-update:semver-minor' || steps.metadata.outputs.update-type == 'version-update:semver-patch') - run: gh pr merge --auto --rebase "$PR_URL" - env: - PR_URL: ${{github.event.pull_request.html_url}} - GH_TOKEN: ${{secrets.GITHUB_TOKEN}} - - - name: Auto-merge dependabot PRs for golang.org updates - if: contains(steps.metadata.outputs.dependency-group, 'golang-org-dependencies') - run: gh pr merge --auto --rebase "$PR_URL" - env: - PR_URL: ${{github.event.pull_request.html_url}} - GH_TOKEN: ${{secrets.GITHUB_TOKEN}} - + permissions: + contents: write + pull-requests: write + uses: go-openapi/ci-workflows/.github/workflows/auto-merge.yml@e77a5bc724d0ab14dd086ee6e13153129ddfe3f9 # v0.2.2 + secrets: inherit diff --git a/.github/workflows/bump-release.yml b/.github/workflows/bump-release.yml new file mode 100644 index 000000000..cb1e9dbb4 --- /dev/null +++ b/.github/workflows/bump-release.yml @@ -0,0 +1,38 @@ +name: Bump Release + +permissions: + contents: read + +on: + workflow_dispatch: + inputs: + bump-type: + description: Type of bump (patch, minor, major) + type: choice + options: + - patch + - minor + - major + default: patch + required: false + tag-message-title: + description: Tag message title to prepend to the release notes + required: false + type: string + tag-message-body: + description: | + Tag message body to prepend to the release notes. + (use "|" to replace end of line). + required: false + type: string + +jobs: + bump-release: + permissions: + contents: write + uses: go-openapi/ci-workflows/.github/workflows/bump-release-monorepo.yml@e77a5bc724d0ab14dd086ee6e13153129ddfe3f9 # v0.2.2 + with: + bump-type: ${{ inputs.bump-type }} + tag-message-title: ${{ inputs.tag-message-title }} + tag-message-body: ${{ inputs.tag-message-body }} + secrets: inherit diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 000000000..07f2445c1 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,22 @@ +name: "CodeQL" + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + paths-ignore: # remove this clause if CodeQL is a required check + - '**/*.md' + schedule: + - cron: '39 19 * * 5' + +permissions: + contents: read + +jobs: + codeql: + permissions: + contents: read + security-events: write + uses: go-openapi/ci-workflows/.github/workflows/codeql.yml@e77a5bc724d0ab14dd086ee6e13153129ddfe3f9 # v0.2.2 + secrets: inherit diff --git a/.github/workflows/contributors.yml b/.github/workflows/contributors.yml new file mode 100644 index 000000000..050010329 --- /dev/null +++ b/.github/workflows/contributors.yml @@ -0,0 +1,18 @@ +name: Contributors + +on: + schedule: + - cron: '18 4 * * 6' + + workflow_dispatch: + +permissions: + contents: read + +jobs: + contributors: + permissions: + pull-requests: write + contents: write + uses: go-openapi/ci-workflows/.github/workflows/contributors.yml@e77a5bc724d0ab14dd086ee6e13153129ddfe3f9 # v0.2.2 + secrets: inherit diff --git a/.github/workflows/go-test.yml b/.github/workflows/go-test.yml index 0437d770c..1f045c3f6 100644 --- a/.github/workflows/go-test.yml +++ b/.github/workflows/go-test.yml @@ -1,221 +1,17 @@ name: go test permissions: - contents: read pull-requests: read + contents: read on: push: - tags: - - v* branches: - master pull_request: jobs: - lint: - name: Go lint mono-repo - runs-on: ubuntu-latest - steps: - - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - with: - fetch-depth: '0' - - - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 - with: - go-version: stable - check-latest: true - cache: true - cache-dependency-path: '**/go.sum' - - - name: Install golangci-lint - uses: golangci/golangci-lint-action@0a35821d5c230e903fcfe077583637dea1b27b47 # v9.0.0 - with: - version: latest - skip-cache: true - install-only: true - - - name: Lint multiple modules - # golangci-lint doesn't support go.work to lint multiple modules in one single pass - run: | - set -euxo pipefail - - git fetch origin master - git show --no-patch --oneline origin/master - - while read module_location ; do - pushd "${module_location}" - golangci-lint run --new-from-rev origin/master - popd - done < <(go list -f '{{.Dir}}' -m) - - module-test: - name: Unit tests - runs-on: ${{ matrix.os }} - needs: [ lint ] - - strategy: - matrix: - os: [ ubuntu-latest, macos-latest, windows-latest ] - go_version: ['oldstable', 'stable' ] - env: - TEST_REPORT: 'all_modules.report.${{ matrix.os }}.${{ matrix.go_version }}.json' - - steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 - with: - go-version: '${{ matrix.go_version }}' - check-latest: true - cache: true - cache-dependency-path: '**/go.sum' - - - name: Ensure TMP is created on windows runners - # On windows, tests require testing.TempDir to reside on the same drive as the code. - # TMP is used by os.TempDir() to determine the location of temporary files. - if: ${{ runner.os == 'Windows' }} - shell: bash - run: | - TMP="${{ github.workspace }}\..\tmp" - mkdir -p ${TMP} - echo "TMP=${TMP}" >> "${GITHUB_ENV}" - - - name: Run unit tests on all modules in this repo - shell: bash - env: - # *.coverage.* pattern is automatically detected by codecov - COVER_PROFILE: 'all_modules.coverage.${{ matrix.os }}.${{ matrix.go_version }}.out' - run: | - # when go1.25 becomes the oldstable, we may replace this bash with "go test work" - declare -a ALL_MODULES - BASH_MAJOR=$(echo $BASH_VERSION|cut -d'.' -f1) - if [[ "${BASH_MAJOR}" -ge 4 ]] ; then - mapfile ALL_MODULES < <(go list -f '{{.Dir}}/...' -m) - else - # for older bash versions, e.g. on macOS runner. This fallback will eventually disappear. - while read line ; do - ALL_MODULES+=("${line}") - done < <(go list -f '{{.Dir}}/...' -m) - fi - echo "::notice title=Modules found::${ALL_MODULES[@]}" - - # with go.work file enabled, go test recognizes sub-modules and collects all packages to be covered - # without specifying -coverpkg. - go test -race -coverprofile="${COVER_PROFILE}" -covermode=atomic -json ${ALL_MODULES[@]}|tee -a "${TEST_REPORT}" - - - name: Upload coverage to codecov - if: ${{ success() }} # we do this only if all previous steps succeeded - uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 - with: - name: Multi modules aggregated coverage - flags: '${{ matrix.go_version }}-${{ matrix.os }}' - fail_ci_if_error: false - verbose: false - - - name: Upload JSON test Results - if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 - with: - name: 'all_modules.report.${{ matrix.os }}.${{ matrix.go_version }}' - path: ${{ env.TEST_REPORT }} - test: - needs: [ module-test ] - name: Test - runs-on: ubuntu-latest - steps: - - name: Tests complete - run: | - echo "::notice title=Success::All tests completed" - - collect-reports: - if: always() - needs: [ module-test ] - name: Collect and merge test reports - runs-on: ubuntu-latest - steps: - - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 - with: - go-version: stable - check-latest: true - cache: true - - - name: Download all JSON artifacts - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 - with: - run-id: "${{ github.run_id }}" - pattern: "all_modules.report.*" - # artifacts resolve as folders - path: reports/ - - - name: Convert test reports to a merged JUnit XML - # NOTE: codecov test reports only support JUnit format at this moment. See https://docs.codecov.com/docs/test-analytics. - # Ideally, codecov improve a bit their platform, so we may only need a single pass to CTRF format. - # - # As a contemplated alternative, we could use gotestsum above to produce the JUnit XML directly. - run: | - go install github.com/jstemmer/go-junit-report/v2@latest - cat reports/*/*.json | go-junit-report -parser gojson -out=reports/junit_report.xml - - - name: Upload test results to Codecov - if: always() - uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 - with: - files: '**/junit_report.xml' - report_type: 'test_results' - fail_ci_if_error: false - handle_no_reports_found: true - verbose: true - - - name: Convert test reports to CTRF JSON - run: | - go install github.com/ctrf-io/go-ctrf-json-reporter/cmd/go-ctrf-json-reporter@v0.0.10 - - appName="swag" - buildNumber="${{ github.run_id }}" - appVersion="${{ github.event.pull_request.head.sha }}" - - while read report ; do - echo "::notice::converting report: ${report}" - #TEST_REPORT: 'all_modules.report.${{ matrix.os }}.${{ matrix.go_version }}.json' - reformated=$(echo "${report##*/}"|sed -E 's/(go)([[:digit:]]+)\.([[:digit:]]+)/\1\2\3/') # e.g. go1.24 becomes go124 - mapfile -d'.' -t -s 2 -n 2 split < <(echo $reformated) # skip the first 2 parts, stop on 2 more parts - osPlatform="${split[0]}" - osRelease="${split[1]}" - - go-ctrf-json-reporter \ - -verbose \ - -appName "${appName}" \ - -appVersion "${appVersion}" \ - -buildNumber "${buildNumber}" \ - -osPlatform "${osPlatform}" \ - -osRelease "${osRelease}" \ - -output "./reports/ctrf_report_${osPlatform}_${osRelease}.json" \ - -quiet < "${report}" - done < <(find reports -name \*.json) - - # NOTE: at this moment, we don't upload CTRF reports as artifacts. - # Some of the CTRF reports are therefore not available (flaky tests, history, ...). - # - # See https://github.com/ctrf-io/github-test-reporter?tab=readme-ov-file#report-showcase - # for more reporting possibilities. At the moment, we keep it simple, as most advanced features - # require a github token (thus adding the complexity of a separate workflow starting on pull_request_target). - # - # For the moment, we are contented with these simple reports. This is an opportunity to compare the insight they - # provide as compared to what is uploaded to codecov. - # - # Codecov analytics are pretty poor at this moment. On the other hand, they manage the bot that pushes back - # PR comments. - # - # They also handle the storage of past test reports, so as to assess flaky tests. - - name: Publish Test Summary Results - uses: ctrf-io/github-test-reporter@024bc4b64d997ca9da86833c6b9548c55c620e40 # v1.0.26 - with: - report-path: 'reports/ctrf_report_*.json' - use-suite-name: true - summary-report: true # post a report to the github actions summary - github-report: true - failed-folded-report: true - + uses: go-openapi/ci-workflows/.github/workflows/go-test-monorepo.yml@e77a5bc724d0ab14dd086ee6e13153129ddfe3f9 # v0.2.2 + secrets: inherit diff --git a/.github/workflows/scanner.yml b/.github/workflows/scanner.yml new file mode 100644 index 000000000..a782af1cb --- /dev/null +++ b/.github/workflows/scanner.yml @@ -0,0 +1,19 @@ +name: Vulnerability scans + +on: + branch_protection_rule: + push: + branches: [ "master" ] + schedule: + - cron: '18 4 * * 3' + +permissions: + contents: read + +jobs: + scanners: + permissions: + contents: read + security-events: write + uses: go-openapi/ci-workflows/.github/workflows/scanner.yml@e77a5bc724d0ab14dd086ee6e13153129ddfe3f9 # V0.1.1 + secrets: inherit diff --git a/.github/workflows/tag-release.yml b/.github/workflows/tag-release.yml new file mode 100644 index 000000000..f9e1de7fa --- /dev/null +++ b/.github/workflows/tag-release.yml @@ -0,0 +1,20 @@ +name: Release on tag + +permissions: + contents: read + +on: + push: + tags: + - v[0-9]+* + +jobs: + gh-release: + name: Create release + permissions: + contents: write + uses: go-openapi/ci-workflows/.github/workflows/release.yml@e77a5bc724d0ab14dd086ee6e13153129ddfe3f9 # v0.2.2 + with: + tag: ${{ github.ref_name }} + is-monorepo: true + secrets: inherit diff --git a/enable/yaml/forward_assertions_test.go b/enable/yaml/forward_assertions_test.go index 6108a3aea..e4cd96bcd 100644 --- a/enable/yaml/forward_assertions_test.go +++ b/enable/yaml/forward_assertions_test.go @@ -13,7 +13,6 @@ func TestYAMLEqWrapper_EqualYAMLString(t *testing.T) { if !assert.YAMLEq(`{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`) { t.Error("YAMLEq should return true") } - } func TestYAMLEqWrapper_EquivalentButNotEqual(t *testing.T) { @@ -23,7 +22,6 @@ func TestYAMLEqWrapper_EquivalentButNotEqual(t *testing.T) { if !assert.YAMLEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) { t.Error("YAMLEq should return true") } - } func TestYAMLEqWrapper_HashOfArraysAndHashes(t *testing.T) { @@ -67,7 +65,6 @@ func TestYAMLEqWrapper_Array(t *testing.T) { if !assert.YAMLEq(`["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`) { t.Error("YAMLEq should return true") } - } func TestYAMLEqWrapper_HashAndArrayNotEquivalent(t *testing.T) { diff --git a/hack/doc-site/hugo/gendoc.sh b/hack/doc-site/hugo/gendoc.sh index 6b3956322..84b049ad8 100755 --- a/hack/doc-site/hugo/gendoc.sh +++ b/hack/doc-site/hugo/gendoc.sh @@ -29,7 +29,7 @@ echo "==> Generated testify.yaml" # Check if theme exists if [ ! -d "themes/hugo-relearn" ]; then echo "ERROR: Relearn theme not found at themes/hugo-relearn" - echo "Run: unzip ../../hugo-theme-relearn-main.zip -d themes/ && mv themes/hugo-theme-relearn-main themes/hugo-relearn" + echo "Run: unzip hugo-theme-relearn-main.zip -d themes/ && mv themes/hugo-theme-relearn-main themes/hugo-relearn" exit 1 fi diff --git a/hack/doc-site/hugo/hugo-theme-relearn-main.zip b/hack/doc-site/hugo/hugo-theme-relearn-main.zip new file mode 100644 index 000000000..80a4c43c6 Binary files /dev/null and b/hack/doc-site/hugo/hugo-theme-relearn-main.zip differ diff --git a/hack/doc-site/hugo/testify.yaml b/hack/doc-site/hugo/testify.yaml index 049c0bc15..55cb50bb9 100644 --- a/hack/doc-site/hugo/testify.yaml +++ b/hack/doc-site/hugo/testify.yaml @@ -13,4 +13,4 @@ params: versionMessage: 'Documentation for Testify v2.0.2' # Build timestamp - buildTime: '2026-01-01T21:42:33Z' + buildTime: '2026-01-02T14:19:49Z' diff --git a/hack/doc-site/hugo/themes/testify-assets/images/favicon.png b/hack/doc-site/hugo/themes/testify-assets/images/favicon.png new file mode 100644 index 000000000..32f319f89 Binary files /dev/null and b/hack/doc-site/hugo/themes/testify-assets/images/favicon.png differ diff --git a/hack/doc-site/hugo/themes/testify-assets/logo.png b/hack/doc-site/hugo/themes/testify-assets/logo.png new file mode 100644 index 000000000..528a099fc Binary files /dev/null and b/hack/doc-site/hugo/themes/testify-assets/logo.png differ diff --git a/hack/doc-site/hugo/themes/testify-static/github.png b/hack/doc-site/hugo/themes/testify-static/github.png new file mode 100644 index 000000000..fe006d4dd Binary files /dev/null and b/hack/doc-site/hugo/themes/testify-static/github.png differ