diff --git a/.github/workflows/scoped-test.yaml b/.github/workflows/scoped-test.yaml new file mode 100644 index 000000000000..0a525de6d64d --- /dev/null +++ b/.github/workflows/scoped-test.yaml @@ -0,0 +1,74 @@ +name: scoped-test + +on: + push: + branches: [ main ] + pull_request: + types: [opened, synchronize, reopened] + +jobs: + changedfiles: + runs-on: ubuntu-latest + if: ${{ github.actor != 'dependabot[bot]' }} + outputs: + go_sources: ${{ steps.changed-files.outputs.sources_all_changed_files }} + go_tests: ${{ steps.changed-files.outputs.tests_all_changed_files }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get changed go files + id: changed-files + uses: tj-actions/changed-files@v45 + with: + files_yaml: | + sources: + - '**/*.go' + - '!**/*_test.go' + tests: + - '**/*_test.go' + + scoped-tests: + strategy: + fail-fast: false + matrix: + os: [ windows-latest ] + runs-on: ${{ matrix.os }} + needs: changedfiles + steps: + - name: Echo changed files + shell: bash + run: | + echo "go_sources: ${{ needs.changedfiles.outputs.go_sources }}" + echo "go_tests: ${{ needs.changedfiles.outputs.go_tests }}" + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: "1.22.8" + cache: false + + - name: Try to restore go-cache + id: go-cache + timeout-minutes: 25 + uses: actions/cache/restore@v4 + with: + path: | + ~/go/bin + ~/go/pkg/mod + ./.tools + key: go-cache-${{ runner.os }}-${{ hashFiles('**/go.sum') }} + + - name: Run changed tests + if: needs.changedfiles.outputs.go_tests + env: + CHANGED_GOLANG_TESTS: ${{ needs.changedfiles.outputs.go_tests }} + run: | + make run-changed-tests + + - name: Run tests on dependent components + if: needs.changedfiles.outputs.go_sources + env: + CHANGED_GOLANG_SOURCES: ${{ needs.changedfiles.outputs.go_sources }} + run: | + make for-affected-components CMD="make test" diff --git a/Makefile.Common b/Makefile.Common index 81b7a0a3ed5a..021a39c847b7 100644 --- a/Makefile.Common +++ b/Makefile.Common @@ -266,3 +266,43 @@ testifylint-fix: gci: $(TOOLS_BIN_DIR)/gci @echo "running $(GCI)" @$(GCI) write -s standard -s default -s "prefix(github.com/open-telemetry/opentelemetry-collector-contrib)" $(ALL_SRC_AND_DOC) + +CHANGED_GOLANG_SOURCES?=$(shell git diff main --name-only | grep -E '.*\.go$$' | grep -v -E '.*_test\.go$$') +.PHONY: for-affected-components +for-affected-components: + @echo "Checking for affected components..." + @if [ -z '$(CHANGED_GOLANG_SOURCES)' ]; then \ + echo "No go source changes detected in shippable code."; \ + else \ + cd $(SRC_ROOT); \ + DEPENDENT_PKGS=$$(echo $(CHANGED_GOLANG_SOURCES) | xargs sed -n 's|^package .* // import "\(.*\)"$$|\1|p' | uniq); \ + if [ -z '$${DEPENDENT_PKGS}' ]; then \ + echo "No other package depends on the one being changed."; \ + else \ + DEPENDENT_PKG_DIRS=$$(echo $${DEPENDENT_PKGS} | tr ' ' '\n' | xargs -I {} grep --include=go.mod -rl {} | xargs dirname | uniq); \ + set -e; for dir in $$(echo $${DEPENDENT_PKG_DIRS}); do \ + (cd "$${dir}" && \ + echo "running $${CMD} in $${dir}" && \ + $${CMD} ); \ + done \ + fi \ + fi + +CHANGED_GOLANG_TESTS?=$(shell git diff main --name-only | grep -E '.*_test\.go$$') +.PHONY: run-changed-tests +run-changed-tests: + @echo "Checking for affected tests..." + @if [ -z '$(CHANGED_GOLANG_TESTS)' ]; then \ + echo "No go test changes detected."; \ + else \ + cd $(SRC_ROOT); \ + AFFECTED_TEST_DIRS=$$(echo $(CHANGED_GOLANG_TESTS) | tr ' ' '\n' | xargs dirname | uniq); \ + if [ -z '$${AFFECTED_TEST_DIRS}' ]; then \ + echo "Failed to find the affected test directories."; \ + else \ + set -e; for dir in $$(echo $${AFFECTED_TEST_DIRS}); do \ + (cd "$${dir}" && \ + $(GOTESTSUM) $(GOTESTSUM_OPT) --packages="./..." -- $(GOTEST_OPT) ); \ + done \ + fi \ + fi