diff --git a/.github/workflows/versions.yml b/.github/workflows/versions.yml index 89f4c42..0758904 100644 --- a/.github/workflows/versions.yml +++ b/.github/workflows/versions.yml @@ -142,6 +142,28 @@ jobs: run: __tests__/verify-go.sh 1.21 shell: bash + auto-detect-go-mod: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest, macos-13] + steps: + - uses: actions/checkout@v5 + - name: Create go.mod in workspace root + run: | + cat > go.mod << 'EOF' + module github.com/actions/setup-go + + go 1.21 + EOF + shell: bash + - name: Setup Go with auto-detection + uses: ./ + - name: Verify go version + run: __tests__/verify-go.sh 1.21 + shell: bash + setup-versions-from-manifest: runs-on: ${{ matrix.os }} strategy: diff --git a/README.md b/README.md index 564d55f..4d9996d 100644 --- a/README.md +++ b/README.md @@ -187,11 +187,25 @@ from thils file will be: The version can specify a patch version or omit it altogether (e.g., `go 1.22.0` or `go 1.22`). -If a patch version is specified, that specific patch version will be used. +If a patch version is specified, that specific patch version will be used. If no patch version is specified, it will search for the latest available patch version in the cache, [versions-manifest.json](https://github.com/actions/go-versions/blob/main/versions-manifest.json), and the [official Go language website](https://golang.org/dl/?mode=json&include=all), in that order. +### Automatic go.mod detection + +**New in v6**: If neither `go-version` nor `go-version-file` is specified, the action will automatically look for a `go.mod` file in the repository root and use the Go version specified in it. This simplifies workflows for projects that already have a `go.mod` file. + +```yaml +steps: + - uses: actions/checkout@v5 + - uses: actions/setup-go@v6 + # Automatically uses go.mod from repository root + - run: go version +``` + +### Specifying a custom path + If both the `go-version` and the `go-version-file` inputs are provided then the `go-version` input is used. > The action will search for the `go.mod` file relative to the repository root diff --git a/__tests__/setup-go.test.ts b/__tests__/setup-go.test.ts index b89c08f..7dc3c03 100644 --- a/__tests__/setup-go.test.ts +++ b/__tests__/setup-go.test.ts @@ -1090,4 +1090,29 @@ use . expect(vars).toStrictEqual({GOTOOLCHAIN: 'local'}); expect(process.env).toHaveProperty('GOTOOLCHAIN', 'local'); }); + + describe('auto-detect go.mod', () => { + it('uses go.mod from workspace root when no inputs provided', async () => { + existsSpy.mockImplementation((filePath: string) => { + return filePath === 'go.mod'; + }); + readFileSpy.mockImplementation(() => + Buffer.from('module test\n\ngo 1.20') + ); + + await main.run(); + + expect(logSpy).toHaveBeenCalledWith('Setup go version spec 1.20'); + }); + + it('uses pre-installed Go when no inputs and no go.mod exists', async () => { + existsSpy.mockImplementation(() => false); + + await main.run(); + + expect(logSpy).toHaveBeenCalledWith( + '[warning]go-version input was not specified. The action will try to use pre-installed version.' + ); + }); + }); }); diff --git a/action.yml b/action.yml index 9946e47..5edb460 100644 --- a/action.yml +++ b/action.yml @@ -5,7 +5,7 @@ inputs: go-version: description: 'The Go version to download (if necessary) and use. Supports semver spec and ranges. Be sure to enclose this option in single quotation marks.' go-version-file: - description: 'Path to the go.mod or go.work file.' + description: 'Path to the go.mod or go.work file. If not specified, the action will automatically use go.mod from the workspace root if it exists.' check-latest: description: 'Set this option to true if you want the action to always check for the latest available version that satisfies the version spec' default: false diff --git a/dist/setup/index.js b/dist/setup/index.js index 96f4ef9..3290c12 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -94902,6 +94902,9 @@ function resolveVersionInput() { } version = installer.parseGoVersionFile(versionFilePath); } + if (!version && fs_1.default.existsSync('go.mod')) { + version = installer.parseGoVersionFile('go.mod'); + } return version; } function setGoToolchain() { diff --git a/src/main.ts b/src/main.ts index 26939ee..9ad747f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -160,6 +160,10 @@ function resolveVersionInput(): string { version = installer.parseGoVersionFile(versionFilePath); } + if (!version && fs.existsSync('go.mod')) { + version = installer.parseGoVersionFile('go.mod'); + } + return version; }