Compare commits

...

1 Commits
v6.2.0 ... main

Author SHA1 Message Date
Priya Gupta
a5f9b05d2d
Update default Go module caching to use go.mod (#705)
* Update module cache to use go.mod as key

* Fix typo

* Revise breaking changes in README for V6

Updated breaking changes section with enhanced formatting and clarified toolchain management details.
2026-01-26 10:59:03 -06:00
8 changed files with 77 additions and 80 deletions

View File

@ -24,24 +24,18 @@ steps:
### V6 Changes
#### Node Runtime Upgrade
**Node Runtime Upgrade**
- **Upgraded from Node 20 to Node 24**
- ⚠️ **Action Required**: Ensure your runner is on version v2.327.1 or later for compatibility
- See [Release Notes](https://github.com/actions/runner/releases/tag/v2.327.1) for more details
#### Enhanced Go Toolchain Management
**Enhanced Go Toolchain Management**
V6 introduces significant improvements for reliable and consistent Go version selection:
V6 introduces significant improvements for reliable and consistent Go version selection. Supports both `go` and `toolchain` directives in `go.mod`. If the `toolchain` directive is present, its version is used; otherwise, the action falls back to the go directive.
**Toolchain Directive Support**
Now correctly interprets both `go` and `toolchain` directives from `go.mod`:
```go
go 1.23.0 // Minimum required version
toolchain go1.23.2 // V6 uses this exact version
```
**Cache Key Update**
**Intelligent Caching**
Cache keys now incorporate the `toolchain` directive version from `go.mod`, eliminating cache conflicts when switching between different toolchain versions within the same Go minor release.
By default, caching for Go modules now relies on `go.mod`. To use `go.sum`, configure the `cache-dependency-path` input.
For more details, see the [full release notes](https://github.com/actions/setup-go/releases/tag/v6.0.0).
@ -257,7 +251,7 @@ The action features integrated caching for Go modules and build outputs. Built o
#### Automatic Caching
Default behavior: Searches for `go.sum` in the repository root and uses its hash for the cache key.
Default behavior: Searches for `go.mod` in the repository root and uses its hash for the cache key.
```yaml
steps:
@ -368,7 +362,7 @@ jobs:
path: |
${{ env.GO_MOD_CACHE }}
${{ env.GO_BUILD_CACHE }}
key: setup-go-${{ runner.os }}-${{ env.ARCH }}-${{ env.CACHE_OS_SUFFIX }}go-${{ steps.setup-go.outputs.go-version }}-${{ hashFiles('**/go.sum') }}
key: setup-go-${{ runner.os }}-${{ env.ARCH }}-${{ env.CACHE_OS_SUFFIX }}go-${{ steps.setup-go.outputs.go-version }}-${{ hashFiles('**/go.mod') }}
- name: Download modules
run: go mod download
- name: Build

View File

@ -1,93 +1,82 @@
import * as cache from '@actions/cache';
import * as core from '@actions/core';
import * as glob from '@actions/glob';
import fs from 'fs';
import * as cacheRestore from '../src/cache-restore';
import * as cacheUtils from '../src/cache-utils';
import {PackageManagerInfo} from '../src/package-managers';
describe('restoreCache', () => {
//Arrange
const hashFilesSpy = jest.spyOn(glob, 'hashFiles');
const getCacheDirectoryPathSpy = jest.spyOn(
cacheUtils,
'getCacheDirectoryPath'
);
const restoreCacheSpy = jest.spyOn(cache, 'restoreCache');
const infoSpy = jest.spyOn(core, 'info');
const setOutputSpy = jest.spyOn(core, 'setOutput');
let hashFilesSpy: jest.SpyInstance;
let getCacheDirectoryPathSpy: jest.SpyInstance;
let restoreCacheSpy: jest.SpyInstance;
let infoSpy: jest.SpyInstance;
let setOutputSpy: jest.SpyInstance;
const versionSpec = '1.13.1';
const packageManager = 'default';
const cacheDependencyPath = 'path';
let originalWorkspace: string | undefined;
beforeEach(() => {
originalWorkspace = process.env.GITHUB_WORKSPACE;
process.env.GITHUB_WORKSPACE = '/test/workspace';
//Arrange
hashFilesSpy = jest.spyOn(glob, 'hashFiles');
getCacheDirectoryPathSpy = jest.spyOn(cacheUtils, 'getCacheDirectoryPath');
restoreCacheSpy = jest.spyOn(cache, 'restoreCache');
infoSpy = jest.spyOn(core, 'info');
setOutputSpy = jest.spyOn(core, 'setOutput');
getCacheDirectoryPathSpy.mockImplementation(
(PackageManager: PackageManagerInfo) => {
return new Promise<string[]>(resolve => {
resolve(['cache_directory_path', 'cache_directory_path']);
});
return Promise.resolve([
'cache_directory_path',
'cache_directory_path'
]);
}
);
});
it('should throw if dependency file path is not valid', async () => {
//Arrange
hashFilesSpy.mockImplementation((somePath: string) => {
return new Promise<string>(resolve => {
resolve('');
});
afterEach(() => {
process.env.GITHUB_WORKSPACE = originalWorkspace;
jest.restoreAllMocks();
});
it('should throw if dependency file path is not valid', async () => {
// Arrange
hashFilesSpy.mockImplementation(() => Promise.resolve(''));
// Act + Assert
await expect(async () => {
await cacheRestore.restoreCache(
await expect(
cacheRestore.restoreCache(
versionSpec,
packageManager,
cacheDependencyPath
);
}).rejects.toThrow(
)
).rejects.toThrow(
'Some specified paths were not resolved, unable to cache dependencies.'
);
});
it('should inform if cache hit is not occured', async () => {
it('should inform if cache hit is not occurred', async () => {
// Arrange
hashFilesSpy.mockImplementation((somePath: string) => {
return new Promise<string>(resolve => {
resolve('file_hash');
});
});
restoreCacheSpy.mockImplementation(() => {
return new Promise<string>(resolve => {
resolve('');
});
});
hashFilesSpy.mockImplementation(() => Promise.resolve('file_hash'));
restoreCacheSpy.mockImplementation(() => Promise.resolve(''));
// Act + Assert
await cacheRestore.restoreCache(
versionSpec,
packageManager,
cacheDependencyPath
);
expect(infoSpy).toHaveBeenCalledWith(`Cache is not found`);
expect(infoSpy).toHaveBeenCalledWith('Cache is not found');
});
it('should set output if cache hit is occured', async () => {
it('should set output if cache hit is occurred', async () => {
// Arrange
hashFilesSpy.mockImplementation((somePath: string) => {
return new Promise<string>(resolve => {
resolve('file_hash');
});
});
restoreCacheSpy.mockImplementation(() => {
return new Promise<string>(resolve => {
resolve('cache_key');
});
});
hashFilesSpy.mockImplementation(() => Promise.resolve('file_hash'));
restoreCacheSpy.mockImplementation(() => Promise.resolve('cache_key'));
// Act + Assert
await cacheRestore.restoreCache(
versionSpec,
@ -96,4 +85,18 @@ describe('restoreCache', () => {
);
expect(setOutputSpy).toHaveBeenCalledWith('cache-hit', true);
});
it('should throw if dependency file is not found in workspace', async () => {
jest.spyOn(fs, 'readdirSync').mockReturnValue(['main.go'] as any);
await expect(
cacheRestore.restoreCache(
versionSpec,
packageManager
// No cacheDependencyPath
)
).rejects.toThrow(
'Dependencies file is not found in /test/workspace. Supported file pattern: go.mod'
);
});
});

View File

@ -47,7 +47,7 @@ describe('getPackageManagerInfo', () => {
//Arrange
const packageManagerName = 'default';
const expectedResult = {
dependencyFilePattern: 'go.sum',
dependencyFilePattern: 'go.mod',
cacheFolderCommandList: ['go env GOMODCACHE', 'go env GOCACHE']
};
@ -73,7 +73,7 @@ describe('getCacheDirectoryPath', () => {
const getExecOutputSpy = jest.spyOn(exec, 'getExecOutput');
const validPackageManager: PackageManagerInfo = {
dependencyFilePattern: 'go.sum',
dependencyFilePattern: 'go.mod',
cacheFolderCommandList: ['go env GOMODCACHE', 'go env GOCACHE']
};

View File

@ -16,7 +16,7 @@ inputs:
description: Used to specify whether caching is needed. Set to true, if you'd like to enable caching.
default: true
cache-dependency-path:
description: 'Used to specify the path to a dependency file - go.sum'
description: 'Used to specify the path to a dependency file (e.g., go.mod, go.sum)'
architecture:
description: 'Target architecture for Go to use. Examples: x86, x64. Will use system architecture by default.'
outputs:

View File

@ -44277,7 +44277,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.supportedPackageManagers = void 0;
exports.supportedPackageManagers = {
default: {
dependencyFilePattern: 'go.sum',
dependencyFilePattern: 'go.mod',
cacheFolderCommandList: ['go env GOMODCACHE', 'go env GOCACHE']
}
};

6
dist/setup/index.js vendored
View File

@ -49364,8 +49364,8 @@ const findDependencyFile = (packageManager) => {
const dependencyFile = packageManager.dependencyFilePattern;
const workspace = process.env.GITHUB_WORKSPACE;
const rootContent = fs_1.default.readdirSync(workspace);
const goSumFileExists = rootContent.includes(dependencyFile);
if (!goSumFileExists) {
const goModFileExists = rootContent.includes(dependencyFile);
if (!goModFileExists) {
throw new Error(`Dependencies file is not found in ${workspace}. Supported file pattern: ${dependencyFile}`);
}
return path_1.default.join(workspace, dependencyFile);
@ -50182,7 +50182,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.supportedPackageManagers = void 0;
exports.supportedPackageManagers = {
default: {
dependencyFilePattern: 'go.sum',
dependencyFilePattern: 'go.mod',
cacheFolderCommandList: ['go env GOMODCACHE', 'go env GOCACHE']
}
};

View File

@ -55,8 +55,8 @@ const findDependencyFile = (packageManager: PackageManagerInfo) => {
const workspace = process.env.GITHUB_WORKSPACE!;
const rootContent = fs.readdirSync(workspace);
const goSumFileExists = rootContent.includes(dependencyFile);
if (!goSumFileExists) {
const goModFileExists = rootContent.includes(dependencyFile);
if (!goModFileExists) {
throw new Error(
`Dependencies file is not found in ${workspace}. Supported file pattern: ${dependencyFile}`
);

View File

@ -9,7 +9,7 @@ export interface PackageManagerInfo {
export const supportedPackageManagers: SupportedPackageManagers = {
default: {
dependencyFilePattern: 'go.sum',
dependencyFilePattern: 'go.mod',
cacheFolderCommandList: ['go env GOMODCACHE', 'go env GOCACHE']
}
};