Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add go-version-from-file option #62

Merged
merged 15 commits into from May 12, 2022
16 changes: 16 additions & 0 deletions .github/workflows/versions.yml
Expand Up @@ -50,6 +50,22 @@ jobs:
- name: Verify Go
run: go version

go-version-file:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v3
- name: Setup Go and check latest
uses: ./
with:
go-version-file: __tests__/data/go.mod
- name: verify go
run: __tests__/verify-go.sh 1.14
shell: bash

setup-versions-from-manifest:
name: Setup ${{ matrix.go }} ${{ matrix.os }}
runs-on: ${{ matrix.os }}
Expand Down
12 changes: 12 additions & 0 deletions __tests__/data/go.mod
@@ -0,0 +1,12 @@
module example.com/mymodule

go 1.14

require (
example.com/othermodule v1.2.3
example.com/thismodule v1.2.3
example.com/thatmodule v1.2.3
)

replace example.com/thatmodule => ../thatmodule
exclude example.com/thismodule v1.3.0
66 changes: 66 additions & 0 deletions __tests__/setup-go.test.ts
Expand Up @@ -33,6 +33,7 @@ describe('setup-go', () => {
let dbgSpy: jest.SpyInstance;
let whichSpy: jest.SpyInstance;
let existsSpy: jest.SpyInstance;
let readFileSpy: jest.SpyInstance;
let mkdirpSpy: jest.SpyInstance;
let execSpy: jest.SpyInstance;
let getManifestSpy: jest.SpyInstance;
Expand Down Expand Up @@ -71,6 +72,7 @@ describe('setup-go', () => {
// io
whichSpy = jest.spyOn(io, 'which');
existsSpy = jest.spyOn(fs, 'existsSync');
readFileSpy = jest.spyOn(fs, 'readFileSync');
mkdirpSpy = jest.spyOn(io, 'mkdirP');

// gets
Expand Down Expand Up @@ -774,4 +776,68 @@ describe('setup-go', () => {
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
});
});

describe('go-version-file', () => {
const goModContents = `module example.com/mymodule

go 1.14

require (
example.com/othermodule v1.2.3
example.com/thismodule v1.2.3
example.com/thatmodule v1.2.3
)

replace example.com/thatmodule => ../thatmodule
exclude example.com/thismodule v1.3.0
`;

it('reads version from go.mod', async () => {
inputs['go-version-file'] = 'go.mod';
existsSpy.mockImplementation(path => true);
readFileSpy.mockImplementation(() => Buffer.from(goModContents));

await main.run();

expect(logSpy).toHaveBeenCalledWith('Setup go version spec 1.14');
expect(logSpy).toHaveBeenCalledWith('Attempting to download 1.14...');
expect(logSpy).toHaveBeenCalledWith('matching 1.14...');
});

it('reads version from .go-version', async () => {
inputs['go-version-file'] = '.go-version';
existsSpy.mockImplementation(path => true);
readFileSpy.mockImplementation(() => Buffer.from(`1.13.0${osm.EOL}`));

await main.run();

expect(logSpy).toHaveBeenCalledWith('Setup go version spec 1.13.0');
expect(logSpy).toHaveBeenCalledWith('Attempting to download 1.13.0...');
expect(logSpy).toHaveBeenCalledWith('matching 1.13.0...');
});

it('is overwritten by go-version', async () => {
inputs['go-version'] = '1.13.1';
inputs['go-version-file'] = 'go.mod';
existsSpy.mockImplementation(path => true);
readFileSpy.mockImplementation(() => Buffer.from(goModContents));

await main.run();

expect(logSpy).toHaveBeenCalledWith('Setup go version spec 1.13.1');
expect(logSpy).toHaveBeenCalledWith('Attempting to download 1.13.1...');
expect(logSpy).toHaveBeenCalledWith('matching 1.13.1...');
});

it('reports a read failure', async () => {
inputs['go-version-file'] = 'go.mod';
existsSpy.mockImplementation(path => false);

await main.run();

expect(cnSpy).toHaveBeenCalledWith(
`::error::The specified go version file at: go.mod does not exist${osm.EOL}`
);
});
});
});
2 changes: 2 additions & 0 deletions action.yml
Expand Up @@ -4,6 +4,8 @@ author: 'GitHub'
inputs:
go-version:
description: 'The Go version to download (if necessary) and use. Supports semver spec and ranges.'
go-version-file:
description: 'Path to the go.mod file.'
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
Expand Down
31 changes: 29 additions & 2 deletions dist/index.js
Expand Up @@ -2074,7 +2074,7 @@ function run() {
// versionSpec is optional. If supplied, install / use from the tool cache
// If not supplied then problem matchers will still be setup. Useful for self-hosted.
//
let versionSpec = core.getInput('go-version');
const versionSpec = resolveVersionInput();
core.info(`Setup go version spec ${versionSpec}`);
if (versionSpec) {
let token = core.getInput('token');
Expand Down Expand Up @@ -2154,6 +2154,23 @@ function parseGoVersion(versionString) {
return versionString.split(' ')[2].slice('go'.length);
}
exports.parseGoVersion = parseGoVersion;
function resolveVersionInput() {
let version = core.getInput('go-version');
const versionFilePath = core.getInput('go-version-file');
if (version && versionFilePath) {
core.warning('Both go-version and go-version-file inputs are specified, only go-version will be used');
}
if (version) {
return version;
}
if (versionFilePath) {
if (!fs_1.default.existsSync(versionFilePath)) {
throw new Error(`The specified go version file at: ${versionFilePath} does not exist`);
}
version = installer.parseGoVersionFile(versionFilePath);
}
return version;
}
//# sourceMappingURL=main.js.map

/***/ }),
Expand Down Expand Up @@ -5894,13 +5911,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.makeSemver = exports.getVersionsDist = exports.findMatch = exports.getInfoFromManifest = exports.extractGoArchive = exports.getGo = void 0;
exports.parseGoVersionFile = exports.makeSemver = exports.getVersionsDist = exports.findMatch = exports.getInfoFromManifest = exports.extractGoArchive = exports.getGo = void 0;
const tc = __importStar(__webpack_require__(533));
const core = __importStar(__webpack_require__(470));
const path = __importStar(__webpack_require__(622));
const semver = __importStar(__webpack_require__(280));
const httpm = __importStar(__webpack_require__(539));
const sys = __importStar(__webpack_require__(737));
const fs_1 = __importDefault(__webpack_require__(747));
const os_1 = __importDefault(__webpack_require__(87));
function getGo(versionSpec, checkLatest, auth) {
return __awaiter(this, void 0, void 0, function* () {
Expand Down Expand Up @@ -6119,6 +6137,15 @@ function makeSemver(version) {
return fullVersion;
}
exports.makeSemver = makeSemver;
function parseGoVersionFile(versionFilePath) {
const contents = fs_1.default.readFileSync(versionFilePath).toString();
if (path.basename(versionFilePath) === 'go.mod') {
const match = contents.match(/^go (\d+(\.\d+)*)/m);
return match ? match[1] : '';
}
return contents.trim();
}
exports.parseGoVersionFile = parseGoVersionFile;
//# sourceMappingURL=installer.js.map

/***/ }),
Expand Down
12 changes: 12 additions & 0 deletions src/installer.ts
Expand Up @@ -4,6 +4,7 @@ import * as path from 'path';
import * as semver from 'semver';
import * as httpm from '@actions/http-client';
import * as sys from './system';
import fs from 'fs';
import os from 'os';

type InstallationType = 'dist' | 'manifest';
Expand Down Expand Up @@ -298,3 +299,14 @@ export function makeSemver(version: string): string {
}
return fullVersion;
}

export function parseGoVersionFile(versionFilePath: string): string {
const contents = fs.readFileSync(versionFilePath).toString();

if (path.basename(versionFilePath) === 'go.mod') {
const match = contents.match(/^go (\d+(\.\d+)*)/m);
return match ? match[1] : '';
}

return contents.trim();
}
28 changes: 27 additions & 1 deletion src/main.ts
Expand Up @@ -13,7 +13,7 @@ export async function run() {
// versionSpec is optional. If supplied, install / use from the tool cache
// If not supplied then problem matchers will still be setup. Useful for self-hosted.
//
let versionSpec = core.getInput('go-version');
const versionSpec = resolveVersionInput();

core.info(`Setup go version spec ${versionSpec}`);

Expand Down Expand Up @@ -104,3 +104,29 @@ export function parseGoVersion(versionString: string): string {
// expecting go<version> for runtime.Version()
return versionString.split(' ')[2].slice('go'.length);
}

function resolveVersionInput(): string {
let version = core.getInput('go-version');
const versionFilePath = core.getInput('go-version-file');

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add here the warning when the user specifies both inputs:

if (version && versionFilePath) {
    core.warning(
      'Both go-version and go-version-file inputs are specified, only go-version will be used'
    );
  }

if (version && versionFilePath) {
core.warning(
'Both go-version and go-version-file inputs are specified, only go-version will be used'
);
}

if (version) {
return version;
}

if (versionFilePath) {
if (!fs.existsSync(versionFilePath)) {
throw new Error(
`The specified go version file at: ${versionFilePath} does not exist`
);
}
version = installer.parseGoVersionFile(versionFilePath);
}

return version;
}