Compare commits

..

No commits in common. "main" and "v9.0.0" have entirely different histories.
main ... v9.0.0

38 changed files with 610 additions and 970 deletions

View file

@ -11,11 +11,6 @@ on:
schedule:
- cron: '0 17 * * 5'
permissions:
actions: read
contents: read
security-events: write
jobs:
codeQL:
# CodeQL runs on ubuntu-latest, windows-latest, and macos-latest
@ -23,7 +18,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v5
with:
# Must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head of the pull request.
@ -41,7 +36,7 @@ jobs:
uses: github/codeql-action/init@v4
# Override language selection by uncommenting this and choosing your languages
with:
languages: 'javascript-typescript'
language: 'javascript'
- run: |
npm install

View file

@ -1,6 +1,5 @@
name: "build-and-test"
on:
on: # rebuild any PRs and main branch changes
pull_request:
branches:
- main
@ -8,27 +7,22 @@ on:
branches:
- main
permissions:
contents: read
jobs:
# make sure build/ci work properly
build:
build: # make sure build/ci work properly
runs-on: ubuntu-latest
steps:
- uses: actions/setup-node@v6
with:
node-version: 24.x
- uses: actions/checkout@v6
- uses: actions/checkout@v5
- run: |
npm install
npm run all
# Fail the build if there are changes.
# Fail the build if there is dirty change
- run: git diff --exit-code -- dist
# make sure the action works on a clean machine without building
test:
test: # make sure the action works on a clean machine without building
needs: [ build ]
strategy:
matrix:
@ -40,14 +34,14 @@ jobs:
version:
- ""
- "latest"
- "v2.7"
- "v2.7.2"
- "v2.5"
- "v2.5.0"
runs-on: ${{ matrix.os }}
permissions:
contents: read
pull-requests: read
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
- uses: actions/setup-node@v6
with:
node-version: 24.x
@ -57,11 +51,10 @@ jobs:
- uses: ./
with:
version: ${{ matrix.version }}
args: --timeout=5m --issues-exit-code=0 ./fixtures/simple/...
args: --timeout=5m --issues-exit-code=0 ./sample/...
only-new-issues: true
# make sure the action works on a clean machine without building (go-install mode)
test-go-install:
test-go-install: # make sure the action works on a clean machine without building (go-install mode)
needs: [ build ]
strategy:
matrix:
@ -73,14 +66,14 @@ jobs:
version:
- ""
- "latest"
- "v2.7.2"
- "v2.5.0"
- "655e8ede5178280b2a640e185bc4a343aed0f54e"
runs-on: ${{ matrix.os }}
permissions:
contents: read
pull-requests: read
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
- uses: actions/setup-node@v6
with:
node-version: 24.x
@ -90,7 +83,7 @@ jobs:
- uses: ./
with:
version: ${{ matrix.version }}
args: --timeout=5m --issues-exit-code=0 ./fixtures/simple/...
args: --timeout=5m --issues-exit-code=0 ./sample/...
only-new-issues: true
install-mode: goinstall
@ -104,13 +97,13 @@ jobs:
- macos-latest
- windows-latest
wd:
- fixtures/go-mod
- fixtures/go-tool
- sample-go-mod
- sample-go-tool
runs-on: ${{ matrix.os }}
permissions:
contents: read
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
- uses: actions/setup-node@v6
with:
node-version: 24.x
@ -122,8 +115,7 @@ jobs:
working-directory: ${{ matrix.wd }}
args: --timeout=5m --issues-exit-code=0 ./...
# make sure the action works on a clean machine with plugins
test-plugins:
test-plugins: # make sure the action works on a clean machine with plugins
needs: [ build ]
strategy:
matrix:
@ -135,14 +127,14 @@ jobs:
version:
- ""
- "latest"
- "v2.7"
- "v2.7.2"
- "v2.5"
- "v2.5.0"
runs-on: ${{ matrix.os }}
permissions:
contents: read
pull-requests: read
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
- uses: actions/setup-node@v6
with:
node-version: 24.x
@ -152,32 +144,5 @@ jobs:
- uses: ./
with:
version: ${{ matrix.version }}
working-directory: fixtures/plugins
args: --timeout=5m --issues-exit-code=0 ./...
test-monorepo:
needs: [ build ]
strategy:
matrix:
os:
- ubuntu-latest
- ubuntu-22.04-arm
- macos-latest
- windows-latest
runs-on: ${{ matrix.os }}
permissions:
contents: read
pull-requests: read
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: 24.x
- uses: actions/setup-go@v6
with:
go-version: oldstable
- uses: ./
with:
working-directory: fixtures/monorepo
experimental: "automatic-module-directories"
working-directory: sample-plugins
args: --timeout=5m --issues-exit-code=0 ./...

258
README.md
View file

@ -54,9 +54,9 @@ jobs:
with:
go-version: stable
- name: golangci-lint
uses: golangci/golangci-lint-action@v9
uses: golangci/golangci-lint-action@v8
with:
version: v2.6
version: v2.1
```
</details>
@ -92,9 +92,9 @@ jobs:
with:
go-version: ${{ matrix.go }}
- name: golangci-lint
uses: golangci/golangci-lint-action@v9
uses: golangci/golangci-lint-action@v8
with:
version: v2.6
version: v2.1
```
You will also likely need to add the following `.gitattributes` file to ensure that line endings for Windows builds are properly formatted:
@ -120,7 +120,7 @@ on:
env:
GO_VERSION: stable
GOLANGCI_LINT_VERSION: v2.6
GOLANGCI_LINT_VERSION: v2.1
jobs:
detect-modules:
@ -147,7 +147,7 @@ jobs:
with:
go-version: ${{ env.GO_VERSION }}
- name: golangci-lint ${{ matrix.modules }}
uses: golangci/golangci-lint-action@v9
uses: golangci/golangci-lint-action@v8
with:
version: ${{ env.GOLANGCI_LINT_VERSION }}
working-directory: ${{ matrix.modules }}
@ -179,7 +179,7 @@ jobs:
with:
os: ${{ matrix.os }}
go-version: ${{ matrix.go-version }}
golangci-lint-version: v2.6
golangci-lint-version: v2.1
```
```yaml
@ -201,7 +201,7 @@ on:
golangci-lint-version:
description: 'Golangci-lint version'
type: string
default: 'v2.6'
default: 'v2.1'
jobs:
detect-modules:
@ -229,7 +229,7 @@ jobs:
with:
go-version: ${{ inputs.go-version }}
- name: golangci-lint ${{ matrix.modules }}
uses: golangci/golangci-lint-action@v9
uses: golangci/golangci-lint-action@v8
with:
version: ${{ inputs.golangci-lint-version }}
working-directory: ${{ matrix.modules }}
@ -259,28 +259,7 @@ You will also likely need to add the following `.gitattributes` file to ensure t
## Options
### Overview
| Option | Description |
|---------------------------------------------------------------|-------------------------------------------------------|
| [`version`](#version) | The version of golangci-lint to use. |
| [`version-file`](#version-file) | Gets the version of golangci-lint to use from a file. |
| [`install-mode`](#install-mode) | The mode to install golangci-lint. |
| [`install-only`](#install-only) | Only install golangci-lint. |
| [`verify`](#verify) | Validates golangci-lint configuration file. |
| [`github-token`](#github-token) | Used by the `only-new-issues` option. |
| [`only-new-issues`](#only-new-issues) | Show only new issues. |
| [`working-directory`](#working-directory) | The golangci-lint working directory. |
| [`args`](#args) | Golangci-lint command line arguments. |
| [`skip-cache`](#skip-cache) | Disable cache support. |
| [`skip-save-cache`](#skip-save-cache) | Don't save cache. |
| [`cache-invalidation-interval`](#cache-invalidation-interval) | Number of days before cache invalidation. |
| [`problem-matchers`](#problem-matchers) | Forces the usage of the embedded problem matchers. |
| [Experimental](#experimental) | Experimental options |
### Installation
#### `version`
### `version`
(optional)
@ -295,37 +274,15 @@ When `install-mode` is:
<summary>Example</summary>
```yml
uses: golangci/golangci-lint-action@v9
uses: golangci/golangci-lint-action@v8
with:
version: v2.6
version: v2.1
# ...
```
</details>
#### `version-file`
Gets the version of golangci-lint to use from a file.
The path must be relative to the root of the project, or the `working-directory` if defined.
This parameter supports `.golangci-lint-version`, and `.tool-versions` files.
Only works with `install-mode: binary` (the default).
<details>
<summary>Example</summary>
```yml
uses: golangci/golangci-lint-action@v9
with:
version-file: .tool-versions
# ...
```
</details>
#### `install-mode`
### `install-mode`
(optional)
@ -339,7 +296,7 @@ The default value is `binary`.
<summary>Example</summary>
```yml
uses: golangci/golangci-lint-action@v9
uses: golangci/golangci-lint-action@v8
with:
install-mode: "none"
# ...
@ -347,7 +304,7 @@ with:
</details>
#### `install-only`
### `install-only`
(optional)
@ -360,7 +317,7 @@ The default value is `false`.
<summary>Example</summary>
```yml
uses: golangci/golangci-lint-action@v9
uses: golangci/golangci-lint-action@v8
with:
install-only: true
# ...
@ -368,9 +325,27 @@ with:
</details>
### Run
### `github-token`
#### `verify`
(optional)
When using the `only-new-issues` option, the GitHub API is used, so a token is required.
By default, it uses the `github.token` from the action.
<details>
<summary>Example</summary>
```yml
uses: golangci/golangci-lint-action@v8
with:
github-token: xxx
# ...
```
</details>
### `verify`
(optional)
@ -385,7 +360,7 @@ The JSON Schema used to validate the configuration depends on the version of gol
<summary>Example</summary>
```yml
uses: golangci/golangci-lint-action@v9
uses: golangci/golangci-lint-action@v8
with:
verify: false
# ...
@ -393,27 +368,7 @@ with:
</details>
#### `github-token`
(optional)
When using the `only-new-issues` option, the GitHub API is used, so a token is required.
By default, it uses the `github.token` from the action.
<details>
<summary>Example</summary>
```yml
uses: golangci/golangci-lint-action@v9
with:
github-token: xxx
# ...
```
</details>
#### `only-new-issues`
### `only-new-issues`
(optional)
@ -430,7 +385,7 @@ The default value is `false`.
<summary>Example</summary>
```yml
uses: golangci/golangci-lint-action@v9
uses: golangci/golangci-lint-action@v8
with:
only-new-issues: true
# ...
@ -438,7 +393,7 @@ with:
</details>
#### `working-directory`
### `working-directory`
(optional)
@ -448,7 +403,7 @@ The golangci-lint working directory, useful for monorepos. The default is the pr
<summary>Example</summary>
```yml
uses: golangci/golangci-lint-action@v9
uses: golangci/golangci-lint-action@v8
with:
working-directory: somedir
# ...
@ -456,7 +411,7 @@ with:
</details>
#### `args`
### `args`
(optional)
@ -473,7 +428,7 @@ golangci-lint command line arguments.
<summary>Example</summary>
```yml
uses: golangci/golangci-lint-action@v9
uses: golangci/golangci-lint-action@v8
with:
# In some rare cases,
# you may need to use `${{ github.workspace }}` as the base directory to reference your configuration file.
@ -483,74 +438,7 @@ with:
</details>
### Cache
#### `skip-cache`
(optional)
If set to `true`, all caching functionality will be completely disabled.
This takes precedence over all other caching options.
The default value is `false`.
<details>
<summary>Example</summary>
```yml
uses: golangci/golangci-lint-action@v9
with:
skip-cache: true
# ...
```
</details>
#### `skip-save-cache`
(optional)
If set to `true`, caches will not be saved, but they may still be restored, requiring `skip-cache: false`.
The default value is `false`.
<details>
<summary>Example</summary>
```yml
uses: golangci/golangci-lint-action@v9
with:
skip-save-cache: true
# ...
```
</details>
#### `cache-invalidation-interval`
(optional)
Periodically invalidate a cache every `cache-invalidation-interval` days to ensure that outdated data is removed and fresh data is loaded.
The default value is `7`.
If the number is `<= 0`, the cache will always be invalidated (not recommended).
<details>
<summary>Example</summary>
```yml
uses: golangci/golangci-lint-action@v9
with:
cache-invalidation-interval: 15
# ...
```
</details>
### Extra
#### `problem-matchers`
### `problem-matchers`
(optional)
@ -568,7 +456,7 @@ The default value is `false`.
<summary>Example</summary>
```yml
uses: golangci/golangci-lint-action@v9
uses: golangci/golangci-lint-action@v8
with:
problem-matchers: true
# ...
@ -576,43 +464,65 @@ with:
</details>
### Experimental
### `skip-cache`
The following options are experimental: those may or may not be supported in the future, and so they will be either converted into a dedicated option or removed.
(optional)
List of comma-separated options.
If set to `true`, all caching functionality will be completely disabled.
This takes precedence over all other caching options.
The default value is `false`.
<details>
<summary>Example</summary>
```yaml
uses: golangci/golangci-lint-action@v9
```yml
uses: golangci/golangci-lint-action@v8
with:
experimental: "foo,bar"
skip-cache: true
# ...
```
</details>
#### `automatic-module-directories`
### `skip-save-cache`
(optional)
This option will run golangci-lint in each module directory, useful for monorepos.
If set to `true`, caches will not be saved, but they may still be restored, requiring `skip-cache: false`.
The automatic detection of modules uses the `working-directory` as the base directory if defined, otherwise the root directory.
> [!IMPORTANT]
> - The cache key will refer to the `working-directory` (if defined) because all the golangci-lint runs must use the same cache directory/key.
> - The version detection will only work if the project has a single module.
> - If the project has multiple modules, the custom build file must be located in the repository root ( or `working-directory`).
The default value is `false`.
<details>
<summary>Example</summary>
```yaml
uses: golangci/golangci-lint-action@v9
```yml
uses: golangci/golangci-lint-action@v8
with:
experimental: "automatic-module-directories"
skip-save-cache: true
# ...
```
</details>
### `cache-invalidation-interval`
(optional)
Periodically invalidate a cache every `cache-invalidation-interval` days to ensure that outdated data is removed and fresh data is loaded.
The default value is `7`.
If the number is `<= 0`, the cache will always be invalidated (not recommended).
<details>
<summary>Example</summary>
```yml
uses: golangci/golangci-lint-action@v8
with:
cache-invalidation-interval: 15
# ...
```
</details>

View file

@ -11,13 +11,6 @@ inputs:
- `goinstall`: the value can be v2.3.4, `latest`, or the hash of a commit.
- `none`: the value is ignored.
required: false
version-file:
description: |
Gets the version of golangci-lint to use from a file.
The path must be relative to the root of the project, or the `working-directory` if defined.
This parameter supports `.golangci-lint-version`, and `.tool-versions` files.
Only works with `install-mode: binary` (the default).
required: false
install-mode:
description: "The mode to install golangci-lint. It can be 'binary', 'goinstall', or 'none'."
default: "binary"
@ -41,10 +34,6 @@ inputs:
description: "If set to true and the action runs on a pull request, the action outputs only newly found issues."
default: 'false'
required: false
args:
description: "golangci-lint command line arguments."
default: ""
required: false
skip-cache:
description: |
If set to true, all caching functionality will be completely disabled.
@ -53,30 +42,21 @@ inputs:
required: false
skip-save-cache:
description: |
If set to true, the action will not save any caches,
but it may still restore existing caches, subject to other options.
If set to true, the action will not save any caches, but it may still
restore existing caches, subject to other options.
default: 'false'
required: false
cache-invalidation-interval:
description: "Periodically invalidate a cache when new code is added (number of days)."
default: '7'
required: false
problem-matchers:
description: "Force the usage of the embedded problem matchers."
default: 'false'
required: false
debug:
description: |
Debug options for the action.
List of comma separated options, the values are `cache`, `clean`.
example: "cache,clean"
args:
description: "golangci-lint command line arguments."
default: ""
required: false
experimental:
description: |
Experimental options for the action.
List of comma separated options.
default: ""
cache-invalidation-interval:
description: "Periodically invalidate a cache when new code is added (number of days)."
default: '7'
required: false
runs:
using: "node24"

235
dist/post_run/index.js generated vendored
View file

@ -96844,10 +96844,8 @@ async function buildCacheKeys() {
return keys;
}
async function restoreCache() {
if (core.getBooleanInput(`skip-cache`, { required: true })) {
core.info(`Skipping cache restoration`);
if (core.getBooleanInput(`skip-cache`, { required: true }))
return;
}
if (!utils.isValidEvent()) {
utils.logWarning(`Event Validation Error: The event type ${process.env[constants_1.Events.Key]} is not supported because it's not tied to a branch or tag ref.`);
return;
@ -96883,14 +96881,10 @@ async function restoreCache() {
}
}
async function saveCache() {
if (core.getBooleanInput(`skip-cache`, { required: true })) {
core.info(`Skipping cache saving`);
if (core.getBooleanInput(`skip-cache`, { required: true }))
return;
}
if (core.getBooleanInput(`skip-save-cache`, { required: true })) {
core.info(`Skipping cache saving`);
if (core.getBooleanInput(`skip-save-cache`, { required: true }))
return;
}
// Validate inputs, this can cause task failure
if (!utils.isValidEvent()) {
utils.logWarning(`Event Validation Error: The event type ${process.env[constants_1.Events.Key]} is not supported because it's not tied to a branch or tag ref.`);
@ -97005,13 +96999,12 @@ exports.installBinary = installBinary;
const core = __importStar(__nccwpck_require__(37484));
const tc = __importStar(__nccwpck_require__(33472));
const child_process_1 = __nccwpck_require__(35317);
const fs_1 = __importDefault(__nccwpck_require__(79896));
const os_1 = __importDefault(__nccwpck_require__(70857));
const path_1 = __importDefault(__nccwpck_require__(16928));
const util_1 = __nccwpck_require__(39023);
const which_1 = __importDefault(__nccwpck_require__(11189));
const version_1 = __nccwpck_require__(311);
const execCommand = (0, util_1.promisify)(child_process_1.exec);
const execShellCommand = (0, util_1.promisify)(child_process_1.exec);
var InstallMode;
(function (InstallMode) {
InstallMode["Binary"] = "binary";
@ -97025,7 +97018,6 @@ const printOutput = (res) => {
if (res.stderr) {
core.info(res.stderr);
}
return res;
};
/**
* Install golangci-lint.
@ -97033,15 +97025,6 @@ const printOutput = (res) => {
* @returns path to installed binary of golangci-lint.
*/
async function install() {
const problemMatchers = core.getBooleanInput(`problem-matchers`);
if (problemMatchers) {
const matchersPath = path_1.default.join(__dirname, "../..", "problem-matchers.json");
if (fs_1.default.existsSync(matchersPath)) {
// Adds problem matchers.
// https://github.com/actions/setup-go/blob/cdcb36043654635271a94b9a6d1392de5bb323a7/src/main.ts#L81-L83
core.info(`##[add-matcher]${matchersPath}`);
}
}
const mode = core.getInput("install-mode").toLowerCase();
if (mode === InstallMode.None) {
const binPath = await (0, which_1.default)("golangci-lint", { nothrow: true });
@ -97081,8 +97064,10 @@ async function goInstall(versionInfo) {
core.info(`Installing golangci-lint ${versionInfo.TargetVersion}...`);
const startedAt = Date.now();
const options = { env: { ...process.env, CGO_ENABLED: "1" } };
await execCommand(`go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@${versionInfo.TargetVersion}`, options).then(printOutput);
const res = await execCommand(`go install -n github.com/golangci/golangci-lint/v2/cmd/golangci-lint@${versionInfo.TargetVersion}`, options).then(printOutput);
const exres = await execShellCommand(`go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@${versionInfo.TargetVersion}`, options);
printOutput(exres);
const res = await execShellCommand(`go install -n github.com/golangci/golangci-lint/v2/cmd/golangci-lint@${versionInfo.TargetVersion}`, options);
printOutput(res);
// The output of `go install -n` when the binary is already installed is `touch <path_to_the_binary>`.
const binPath = res.stderr
.split(/\r?\n/)
@ -97211,6 +97196,9 @@ function isOnlyNewIssues() {
return core.getBooleanInput(`only-new-issues`, { required: true });
}
async function fetchPatch() {
if (!isOnlyNewIssues()) {
return ``;
}
const ctx = github.context;
switch (ctx.eventName) {
case `pull_request`:
@ -97254,7 +97242,8 @@ async function fetchPullRequestPatch(ctx) {
return ``; // don't fail the action, but analyze without patch
}
try {
const patchPath = await createTempDir().then((tempDir) => path_1.default.join(tempDir, "pull.patch"));
const tempDir = await createTempDir();
const patchPath = path_1.default.join(tempDir, "pull.patch");
core.info(`Writing patch to ${patchPath}`);
await writeFile(patchPath, (0, diffUtils_1.alterDiffPatch)(patch));
return patchPath;
@ -97288,7 +97277,8 @@ async function fetchPushPatch(ctx) {
return ``; // don't fail the action, but analyze without patch
}
try {
const patchPath = await createTempDir().then((tempDir) => path_1.default.join(tempDir, "push.patch"));
const tempDir = await createTempDir();
const patchPath = path_1.default.join(tempDir, "push.patch");
core.info(`Writing patch to ${patchPath}`);
await writeFile(patchPath, (0, diffUtils_1.alterDiffPatch)(patch));
return patchPath;
@ -97351,7 +97341,7 @@ const fs = __importStar(__nccwpck_require__(79896));
const path = __importStar(__nccwpck_require__(16928));
const util_1 = __nccwpck_require__(39023);
const yaml_1 = __importDefault(__nccwpck_require__(38815));
const execCommand = (0, util_1.promisify)(child_process_1.exec);
const execShellCommand = (0, util_1.promisify)(child_process_1.exec);
const printOutput = (res) => {
if (res.stdout) {
core.info(res.stdout);
@ -97371,12 +97361,11 @@ async function install(binPath) {
else {
rootDir = process.cwd();
}
const configFile = ["yml", "yaml", "json"]
.map((ext) => `.custom-gcl.${ext}`)
.map((filename) => path.join(rootDir, filename))
const configFile = [".custom-gcl.yml", ".custom-gcl.yaml", ".custom-gcl.json"]
.map((v) => path.join(rootDir, v))
.find((filePath) => fs.existsSync(filePath));
if (!configFile || configFile === "") {
return binPath;
return "";
}
core.info(`Found configuration for the plugin module system : ${configFile}`);
core.info(`Building and installing custom golangci-lint binary...`);
@ -97384,7 +97373,7 @@ async function install(binPath) {
const config = yaml_1.default.parse(fs.readFileSync(configFile, "utf-8"));
const v = core.getInput(`version`);
if (v !== "" && config.version !== v) {
core.warning(`The golangci-lint version (${config.version}) defined inside ${configFile} does not match the version defined in the action (${v})`);
core.warning(`The golangci-lint version (${config.version}) defined inside in ${configFile} does not match the version defined in the action (${v})`);
}
if (!config.destination) {
config.destination = ".";
@ -97398,16 +97387,18 @@ async function install(binPath) {
}
const cmd = `${binPath} custom`;
core.info(`Running [${cmd}] in [${rootDir}] ...`);
const options = {
cwd: rootDir,
};
return execCommand(cmd, options)
.then(printOutput)
.then(() => core.info(`Built custom golangci-lint binary in ${Date.now() - startedAt}ms`))
.then(() => path.join(rootDir, config.destination, config.name))
.catch((exc) => {
try {
const options = {
cwd: rootDir,
};
const res = await execShellCommand(cmd, options);
printOutput(res);
core.info(`Built custom golangci-lint binary in ${Date.now() - startedAt}ms`);
return path.join(rootDir, config.destination, config.name);
}
catch (exc) {
throw new Error(`Failed to build custom golangci-lint binary: ${exc.message}`);
});
}
}
@ -97464,7 +97455,24 @@ const cache_1 = __nccwpck_require__(97377);
const install_1 = __nccwpck_require__(90232);
const patch_1 = __nccwpck_require__(47161);
const plugins = __importStar(__nccwpck_require__(96067));
const execCommand = (0, util_1.promisify)(child_process_1.exec);
const execShellCommand = (0, util_1.promisify)(child_process_1.exec);
async function prepareEnv(installOnly) {
const startedAt = Date.now();
// Prepare cache, lint and go in parallel.
await (0, cache_1.restoreCache)();
let binPath = await (0, install_1.install)();
// Build custom golangci-lint if needed.
const customBinPath = await plugins.install(binPath);
if (customBinPath !== "") {
binPath = customBinPath;
}
if (installOnly) {
return { binPath, patchPath: `` };
}
const patchPath = await (0, patch_1.fetchPatch)();
core.info(`Prepared env in ${Date.now() - startedAt}ms`);
return { binPath, patchPath };
}
const printOutput = (res) => {
if (res.stdout) {
core.info(res.stdout);
@ -97473,7 +97481,12 @@ const printOutput = (res) => {
core.info(res.stderr);
}
};
async function runGolangciLint(binPath, rootDir) {
async function runLint(binPath, patchPath) {
const debug = core.getInput(`debug`);
if (debug.split(`,`).includes(`cache`)) {
const res = await execShellCommand(`${binPath} cache status`);
printOutput(res);
}
const userArgs = core.getInput(`args`);
const addedArgs = [];
const userArgsList = userArgs
@ -97485,6 +97498,15 @@ async function runGolangciLint(binPath, rootDir) {
.map(([key, value]) => [key.toLowerCase(), value ?? ""]);
const userArgsMap = new Map(userArgsList);
const userArgNames = new Set(userArgsList.map(([key]) => key));
const problemMatchers = core.getBooleanInput(`problem-matchers`);
if (problemMatchers) {
const matchersPath = path.join(__dirname, "../..", "problem-matchers.json");
if (fs.existsSync(matchersPath)) {
// Adds problem matchers.
// https://github.com/actions/setup-go/blob/cdcb36043654635271a94b9a6d1392de5bb323a7/src/main.ts#L81-L83
core.info(`##[add-matcher]${matchersPath}`);
}
}
if ((0, patch_1.isOnlyNewIssues)()) {
if (userArgNames.has(`new`) ||
userArgNames.has(`new-from-rev`) ||
@ -97493,7 +97515,6 @@ async function runGolangciLint(binPath, rootDir) {
throw new Error(`please, don't specify manually --new* args when requesting only new issues`);
}
const ctx = github.context;
const patchPath = await (0, patch_1.fetchPatch)();
core.info(`only new issues on ${ctx.eventName}: ${patchPath}`);
switch (ctx.eventName) {
case `pull_request`:
@ -97519,21 +97540,27 @@ async function runGolangciLint(binPath, rootDir) {
}
}
const cmdArgs = {};
if (rootDir) {
const workingDirectory = core.getInput(`working-directory`);
if (workingDirectory) {
if (!fs.existsSync(workingDirectory) || !fs.lstatSync(workingDirectory).isDirectory()) {
throw new Error(`working-directory (${workingDirectory}) was not a path`);
}
if (!userArgNames.has(`path-prefix`) && !userArgNames.has(`path-mode`)) {
addedArgs.push(`--path-mode=abs`);
}
cmdArgs.cwd = path.resolve(rootDir);
cmdArgs.cwd = path.resolve(workingDirectory);
}
await runVerify(binPath, userArgsMap, cmdArgs);
const cmd = `${binPath} run ${addedArgs.join(` `)} ${userArgs}`.trimEnd();
core.info(`Running [${cmd}] in [${cmdArgs.cwd || process.cwd()}] ...`);
const startedAt = Date.now();
return execCommand(cmd, cmdArgs)
.then(printOutput)
.then(() => core.info(`golangci-lint found no issues`))
.catch((exc) => {
// This logging passes issues to GitHub annotations.
try {
const res = await execShellCommand(cmd, cmdArgs);
printOutput(res);
core.info(`golangci-lint found no issues`);
}
catch (exc) {
// This logging passes issues to GitHub annotations but comments can be more convenient for some users.
printOutput(exc);
if (exc.code === 1) {
core.setFailed(`issues found`);
@ -97541,8 +97568,8 @@ async function runGolangciLint(binPath, rootDir) {
else {
core.setFailed(`golangci-lint exit with code ${exc.code}`);
}
})
.finally(() => core.info(`Ran golangci-lint in ${Date.now() - startedAt}ms`));
}
core.info(`Ran golangci-lint in ${Date.now() - startedAt}ms`);
}
async function runVerify(binPath, userArgsMap, cmdArgs) {
const verify = core.getBooleanInput(`verify`, { required: true });
@ -97558,7 +97585,8 @@ async function runVerify(binPath, userArgsMap, cmdArgs) {
cmdVerify += ` --config=${userArgsMap.get("config")}`;
}
core.info(`Running [${cmdVerify}] in [${cmdArgs.cwd || process.cwd()}] ...`);
await execCommand(cmdVerify, cmdArgs).then(printOutput);
const res = await execShellCommand(cmdVerify, cmdArgs);
printOutput(res);
}
async function getConfigPath(binPath, userArgsMap, cmdArgs) {
let cmdConfigPath = `${binPath} config path`;
@ -97567,73 +97595,22 @@ async function getConfigPath(binPath, userArgsMap, cmdArgs) {
}
core.info(`Running [${cmdConfigPath}] in [${cmdArgs.cwd || process.cwd()}] ...`);
try {
const resPath = await execCommand(cmdConfigPath, cmdArgs);
const resPath = await execShellCommand(cmdConfigPath, cmdArgs);
return resPath.stderr.trim();
}
catch {
return ``;
}
}
async function debugAction(binPath) {
const flags = core.getInput(`debug`).split(`,`);
if (flags.includes(`clean`)) {
const cmd = `${binPath} cache clean`;
core.info(`Running [${cmd}] ...`);
await execCommand(cmd).then(printOutput);
}
if (flags.includes(`cache`)) {
const cmd = `${binPath} cache status`;
core.info(`Running [${cmd}] ...`);
await execCommand(cmd).then(printOutput);
}
}
function getWorkingDirectory() {
const workingDirectory = core.getInput(`working-directory`);
if (workingDirectory) {
if (!fs.existsSync(workingDirectory) || !fs.lstatSync(workingDirectory).isDirectory()) {
throw new Error(`working-directory (${workingDirectory}) was not a path`);
}
}
return workingDirectory;
}
function modulesAutoDetection(rootDir) {
const o = {
cwd: rootDir,
exclude: ["**/vendor/**", "**/node_modules/**", "**/.git/**", "**/dist/**"],
};
const matches = fs.globSync("**/go.mod", o);
const dirs = matches
.filter((m) => typeof m === "string")
.map((m) => path.resolve(rootDir, path.dirname(m)))
.sort();
return [...new Set(dirs)];
}
async function runLint(binPath) {
const workingDirectory = getWorkingDirectory();
const experimental = core.getInput(`experimental`).split(`,`);
if (experimental.includes(`automatic-module-directories`)) {
const wds = modulesAutoDetection(workingDirectory);
const cwd = process.cwd();
for (const wd of wds) {
await core.group(`run golangci-lint in ${path.relative(cwd, wd)}`, () => runGolangciLint(binPath, wd));
}
return;
}
await core.group(`run golangci-lint`, () => runGolangciLint(binPath, workingDirectory));
}
async function run() {
try {
await core.group(`Restore cache`, cache_1.restoreCache);
const binPath = await core.group(`Install`, () => (0, install_1.install)().then(plugins.install));
core.addPath(path.dirname(binPath));
if (core.getInput(`debug`)) {
await core.group(`Debug`, () => debugAction(binPath));
}
const installOnly = core.getBooleanInput(`install-only`, { required: true });
const { binPath, patchPath } = await core.group(`prepare environment`, () => prepareEnv(installOnly));
core.addPath(path.dirname(binPath));
if (installOnly) {
return;
}
await runLint(binPath);
await core.group(`run golangci-lint`, () => runLint(binPath, patchPath));
}
catch (error) {
core.error(`Failed to run: ${error}, ${error.stack}`);
@ -97912,10 +97889,6 @@ const isLessVersion = (a, b) => {
};
const getRequestedVersion = () => {
let requestedVersion = core.getInput(`version`);
let versionFilePath = core.getInput(`version-file`);
if (requestedVersion && versionFilePath) {
core.warning(`Both version (${requestedVersion}) and version-file (${versionFilePath}) inputs are specified, only version will be used`);
}
const workingDirectory = core.getInput(`working-directory`);
let goMod = "go.mod";
if (workingDirectory) {
@ -97929,24 +97902,6 @@ const getRequestedVersion = () => {
core.info(`Found golangci-lint version '${requestedVersion}' in '${goMod}' file`);
}
}
if (requestedVersion == "" && versionFilePath) {
if (workingDirectory) {
versionFilePath = path_1.default.join(workingDirectory, versionFilePath);
}
if (!fs.existsSync(versionFilePath)) {
throw new Error(`The specified golangci-lint version file at: ${versionFilePath} does not exist`);
}
const content = fs.readFileSync(versionFilePath, "utf-8");
if (path_1.default.basename(versionFilePath) === ".tool-versions") {
// asdf/mise file.
const match = content.match(/^golangci-lint\s+([^\n#]+)/m);
requestedVersion = match ? "v" + match[1].trim().replace(/^v/gi, "") : "";
}
else {
// .golangci-lint-version file.
requestedVersion = "v" + content.trim().replace(/^v/gi, "");
}
}
const parsedRequestedVersion = parseVersion(requestedVersion);
if (parsedRequestedVersion == null) {
return null;
@ -102728,7 +102683,7 @@ function composeCollection(CN, ctx, token, props, onError) {
let tag = ctx.schema.tags.find(t => t.tag === tagName && t.collection === expType);
if (!tag) {
const kt = ctx.schema.knownTags[tagName];
if (kt?.collection === expType) {
if (kt && kt.collection === expType) {
ctx.schema.tags.push(Object.assign({}, kt, { default: false }));
tag = kt;
}
@ -103614,7 +103569,7 @@ function resolveBlockSeq({ composeNode, composeEmptyNode }, ctx, bs, onError, ta
});
if (!props.found) {
if (props.anchor || props.tag || value) {
if (value?.type === 'block-seq')
if (value && value.type === 'block-seq')
onError(props.end, 'BAD_INDENT', 'All sequence items must start at the same column');
else
onError(offset, 'MISSING_CHAR', 'Sequence item without - indicator');
@ -103831,7 +103786,7 @@ function resolveFlowCollection({ composeNode, composeEmptyNode }, ctx, fc, onErr
}
}
else if (value) {
if ('source' in value && value.source?.[0] === ':')
if ('source' in value && value.source && value.source[0] === ':')
onError(value, 'MISSING_CHAR', `Missing space after : in ${fcName}`);
else
onError(valueProps.start, 'MISSING_CHAR', `Missing , or : between ${fcName} items`);
@ -103875,7 +103830,7 @@ function resolveFlowCollection({ composeNode, composeEmptyNode }, ctx, fc, onErr
const expectedEnd = isMap ? '}' : ']';
const [ce, ...ee] = fc.end;
let cePos = offset;
if (ce?.source === expectedEnd)
if (ce && ce.source === expectedEnd)
cePos = ce.offset + ce.source.length;
else {
const name = fcName[0].toUpperCase() + fcName.substring(1);
@ -105256,7 +105211,7 @@ const prettifyError = (src, lc) => (error) => {
if (/[^ ]/.test(lineStr)) {
let count = 1;
const end = error.linePos[1];
if (end?.line === line && end.col > col) {
if (end && end.line === line && end.col > col) {
count = Math.max(1, Math.min(end.col - col, 80 - ci));
}
const pointer = ' '.repeat(ci) + '^'.repeat(count);
@ -105424,7 +105379,7 @@ class Alias extends Node.NodeBase {
data = anchors.get(source);
}
/* istanbul ignore if */
if (data?.res === undefined) {
if (!data || data.res === undefined) {
const msg = 'This should not happen: Alias anchor was not resolved?';
throw new ReferenceError(msg);
}
@ -107766,7 +107721,7 @@ class Parser {
}
*step() {
const top = this.peek(1);
if (this.type === 'doc-end' && top?.type !== 'doc-end') {
if (this.type === 'doc-end' && (!top || top.type !== 'doc-end')) {
while (this.stack.length > 0)
yield* this.pop();
this.stack.push({
@ -108298,7 +108253,7 @@ class Parser {
do {
yield* this.pop();
top = this.peek(1);
} while (top?.type === 'flow-collection');
} while (top && top.type === 'flow-collection');
}
else if (fc.end.length === 0) {
switch (this.type) {
@ -110484,7 +110439,7 @@ function stringifyNumber({ format, minFractionDigits, tag, value }) {
const num = typeof value === 'number' ? value : Number(value);
if (!isFinite(num))
return isNaN(num) ? '.nan' : num < 0 ? '-.inf' : '.inf';
let n = Object.is(value, -0) ? '-0' : JSON.stringify(value);
let n = JSON.stringify(value);
if (!format &&
minFractionDigits &&
(!tag || tag === 'tag:yaml.org,2002:float') &&
@ -110615,7 +110570,7 @@ function stringifyPair({ key, value }, ctx, onComment, onChompKeep) {
ws += `\n${stringifyComment.indentComment(cs, ctx.indent)}`;
}
if (valueStr === '' && !ctx.inFlow) {
if (ws === '\n' && valueComment)
if (ws === '\n')
ws = '\n\n';
}
else {

235
dist/run/index.js generated vendored
View file

@ -96844,10 +96844,8 @@ async function buildCacheKeys() {
return keys;
}
async function restoreCache() {
if (core.getBooleanInput(`skip-cache`, { required: true })) {
core.info(`Skipping cache restoration`);
if (core.getBooleanInput(`skip-cache`, { required: true }))
return;
}
if (!utils.isValidEvent()) {
utils.logWarning(`Event Validation Error: The event type ${process.env[constants_1.Events.Key]} is not supported because it's not tied to a branch or tag ref.`);
return;
@ -96883,14 +96881,10 @@ async function restoreCache() {
}
}
async function saveCache() {
if (core.getBooleanInput(`skip-cache`, { required: true })) {
core.info(`Skipping cache saving`);
if (core.getBooleanInput(`skip-cache`, { required: true }))
return;
}
if (core.getBooleanInput(`skip-save-cache`, { required: true })) {
core.info(`Skipping cache saving`);
if (core.getBooleanInput(`skip-save-cache`, { required: true }))
return;
}
// Validate inputs, this can cause task failure
if (!utils.isValidEvent()) {
utils.logWarning(`Event Validation Error: The event type ${process.env[constants_1.Events.Key]} is not supported because it's not tied to a branch or tag ref.`);
@ -97005,13 +96999,12 @@ exports.installBinary = installBinary;
const core = __importStar(__nccwpck_require__(37484));
const tc = __importStar(__nccwpck_require__(33472));
const child_process_1 = __nccwpck_require__(35317);
const fs_1 = __importDefault(__nccwpck_require__(79896));
const os_1 = __importDefault(__nccwpck_require__(70857));
const path_1 = __importDefault(__nccwpck_require__(16928));
const util_1 = __nccwpck_require__(39023);
const which_1 = __importDefault(__nccwpck_require__(11189));
const version_1 = __nccwpck_require__(311);
const execCommand = (0, util_1.promisify)(child_process_1.exec);
const execShellCommand = (0, util_1.promisify)(child_process_1.exec);
var InstallMode;
(function (InstallMode) {
InstallMode["Binary"] = "binary";
@ -97025,7 +97018,6 @@ const printOutput = (res) => {
if (res.stderr) {
core.info(res.stderr);
}
return res;
};
/**
* Install golangci-lint.
@ -97033,15 +97025,6 @@ const printOutput = (res) => {
* @returns path to installed binary of golangci-lint.
*/
async function install() {
const problemMatchers = core.getBooleanInput(`problem-matchers`);
if (problemMatchers) {
const matchersPath = path_1.default.join(__dirname, "../..", "problem-matchers.json");
if (fs_1.default.existsSync(matchersPath)) {
// Adds problem matchers.
// https://github.com/actions/setup-go/blob/cdcb36043654635271a94b9a6d1392de5bb323a7/src/main.ts#L81-L83
core.info(`##[add-matcher]${matchersPath}`);
}
}
const mode = core.getInput("install-mode").toLowerCase();
if (mode === InstallMode.None) {
const binPath = await (0, which_1.default)("golangci-lint", { nothrow: true });
@ -97081,8 +97064,10 @@ async function goInstall(versionInfo) {
core.info(`Installing golangci-lint ${versionInfo.TargetVersion}...`);
const startedAt = Date.now();
const options = { env: { ...process.env, CGO_ENABLED: "1" } };
await execCommand(`go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@${versionInfo.TargetVersion}`, options).then(printOutput);
const res = await execCommand(`go install -n github.com/golangci/golangci-lint/v2/cmd/golangci-lint@${versionInfo.TargetVersion}`, options).then(printOutput);
const exres = await execShellCommand(`go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@${versionInfo.TargetVersion}`, options);
printOutput(exres);
const res = await execShellCommand(`go install -n github.com/golangci/golangci-lint/v2/cmd/golangci-lint@${versionInfo.TargetVersion}`, options);
printOutput(res);
// The output of `go install -n` when the binary is already installed is `touch <path_to_the_binary>`.
const binPath = res.stderr
.split(/\r?\n/)
@ -97211,6 +97196,9 @@ function isOnlyNewIssues() {
return core.getBooleanInput(`only-new-issues`, { required: true });
}
async function fetchPatch() {
if (!isOnlyNewIssues()) {
return ``;
}
const ctx = github.context;
switch (ctx.eventName) {
case `pull_request`:
@ -97254,7 +97242,8 @@ async function fetchPullRequestPatch(ctx) {
return ``; // don't fail the action, but analyze without patch
}
try {
const patchPath = await createTempDir().then((tempDir) => path_1.default.join(tempDir, "pull.patch"));
const tempDir = await createTempDir();
const patchPath = path_1.default.join(tempDir, "pull.patch");
core.info(`Writing patch to ${patchPath}`);
await writeFile(patchPath, (0, diffUtils_1.alterDiffPatch)(patch));
return patchPath;
@ -97288,7 +97277,8 @@ async function fetchPushPatch(ctx) {
return ``; // don't fail the action, but analyze without patch
}
try {
const patchPath = await createTempDir().then((tempDir) => path_1.default.join(tempDir, "push.patch"));
const tempDir = await createTempDir();
const patchPath = path_1.default.join(tempDir, "push.patch");
core.info(`Writing patch to ${patchPath}`);
await writeFile(patchPath, (0, diffUtils_1.alterDiffPatch)(patch));
return patchPath;
@ -97351,7 +97341,7 @@ const fs = __importStar(__nccwpck_require__(79896));
const path = __importStar(__nccwpck_require__(16928));
const util_1 = __nccwpck_require__(39023);
const yaml_1 = __importDefault(__nccwpck_require__(38815));
const execCommand = (0, util_1.promisify)(child_process_1.exec);
const execShellCommand = (0, util_1.promisify)(child_process_1.exec);
const printOutput = (res) => {
if (res.stdout) {
core.info(res.stdout);
@ -97371,12 +97361,11 @@ async function install(binPath) {
else {
rootDir = process.cwd();
}
const configFile = ["yml", "yaml", "json"]
.map((ext) => `.custom-gcl.${ext}`)
.map((filename) => path.join(rootDir, filename))
const configFile = [".custom-gcl.yml", ".custom-gcl.yaml", ".custom-gcl.json"]
.map((v) => path.join(rootDir, v))
.find((filePath) => fs.existsSync(filePath));
if (!configFile || configFile === "") {
return binPath;
return "";
}
core.info(`Found configuration for the plugin module system : ${configFile}`);
core.info(`Building and installing custom golangci-lint binary...`);
@ -97384,7 +97373,7 @@ async function install(binPath) {
const config = yaml_1.default.parse(fs.readFileSync(configFile, "utf-8"));
const v = core.getInput(`version`);
if (v !== "" && config.version !== v) {
core.warning(`The golangci-lint version (${config.version}) defined inside ${configFile} does not match the version defined in the action (${v})`);
core.warning(`The golangci-lint version (${config.version}) defined inside in ${configFile} does not match the version defined in the action (${v})`);
}
if (!config.destination) {
config.destination = ".";
@ -97398,16 +97387,18 @@ async function install(binPath) {
}
const cmd = `${binPath} custom`;
core.info(`Running [${cmd}] in [${rootDir}] ...`);
const options = {
cwd: rootDir,
};
return execCommand(cmd, options)
.then(printOutput)
.then(() => core.info(`Built custom golangci-lint binary in ${Date.now() - startedAt}ms`))
.then(() => path.join(rootDir, config.destination, config.name))
.catch((exc) => {
try {
const options = {
cwd: rootDir,
};
const res = await execShellCommand(cmd, options);
printOutput(res);
core.info(`Built custom golangci-lint binary in ${Date.now() - startedAt}ms`);
return path.join(rootDir, config.destination, config.name);
}
catch (exc) {
throw new Error(`Failed to build custom golangci-lint binary: ${exc.message}`);
});
}
}
@ -97464,7 +97455,24 @@ const cache_1 = __nccwpck_require__(97377);
const install_1 = __nccwpck_require__(90232);
const patch_1 = __nccwpck_require__(47161);
const plugins = __importStar(__nccwpck_require__(96067));
const execCommand = (0, util_1.promisify)(child_process_1.exec);
const execShellCommand = (0, util_1.promisify)(child_process_1.exec);
async function prepareEnv(installOnly) {
const startedAt = Date.now();
// Prepare cache, lint and go in parallel.
await (0, cache_1.restoreCache)();
let binPath = await (0, install_1.install)();
// Build custom golangci-lint if needed.
const customBinPath = await plugins.install(binPath);
if (customBinPath !== "") {
binPath = customBinPath;
}
if (installOnly) {
return { binPath, patchPath: `` };
}
const patchPath = await (0, patch_1.fetchPatch)();
core.info(`Prepared env in ${Date.now() - startedAt}ms`);
return { binPath, patchPath };
}
const printOutput = (res) => {
if (res.stdout) {
core.info(res.stdout);
@ -97473,7 +97481,12 @@ const printOutput = (res) => {
core.info(res.stderr);
}
};
async function runGolangciLint(binPath, rootDir) {
async function runLint(binPath, patchPath) {
const debug = core.getInput(`debug`);
if (debug.split(`,`).includes(`cache`)) {
const res = await execShellCommand(`${binPath} cache status`);
printOutput(res);
}
const userArgs = core.getInput(`args`);
const addedArgs = [];
const userArgsList = userArgs
@ -97485,6 +97498,15 @@ async function runGolangciLint(binPath, rootDir) {
.map(([key, value]) => [key.toLowerCase(), value ?? ""]);
const userArgsMap = new Map(userArgsList);
const userArgNames = new Set(userArgsList.map(([key]) => key));
const problemMatchers = core.getBooleanInput(`problem-matchers`);
if (problemMatchers) {
const matchersPath = path.join(__dirname, "../..", "problem-matchers.json");
if (fs.existsSync(matchersPath)) {
// Adds problem matchers.
// https://github.com/actions/setup-go/blob/cdcb36043654635271a94b9a6d1392de5bb323a7/src/main.ts#L81-L83
core.info(`##[add-matcher]${matchersPath}`);
}
}
if ((0, patch_1.isOnlyNewIssues)()) {
if (userArgNames.has(`new`) ||
userArgNames.has(`new-from-rev`) ||
@ -97493,7 +97515,6 @@ async function runGolangciLint(binPath, rootDir) {
throw new Error(`please, don't specify manually --new* args when requesting only new issues`);
}
const ctx = github.context;
const patchPath = await (0, patch_1.fetchPatch)();
core.info(`only new issues on ${ctx.eventName}: ${patchPath}`);
switch (ctx.eventName) {
case `pull_request`:
@ -97519,21 +97540,27 @@ async function runGolangciLint(binPath, rootDir) {
}
}
const cmdArgs = {};
if (rootDir) {
const workingDirectory = core.getInput(`working-directory`);
if (workingDirectory) {
if (!fs.existsSync(workingDirectory) || !fs.lstatSync(workingDirectory).isDirectory()) {
throw new Error(`working-directory (${workingDirectory}) was not a path`);
}
if (!userArgNames.has(`path-prefix`) && !userArgNames.has(`path-mode`)) {
addedArgs.push(`--path-mode=abs`);
}
cmdArgs.cwd = path.resolve(rootDir);
cmdArgs.cwd = path.resolve(workingDirectory);
}
await runVerify(binPath, userArgsMap, cmdArgs);
const cmd = `${binPath} run ${addedArgs.join(` `)} ${userArgs}`.trimEnd();
core.info(`Running [${cmd}] in [${cmdArgs.cwd || process.cwd()}] ...`);
const startedAt = Date.now();
return execCommand(cmd, cmdArgs)
.then(printOutput)
.then(() => core.info(`golangci-lint found no issues`))
.catch((exc) => {
// This logging passes issues to GitHub annotations.
try {
const res = await execShellCommand(cmd, cmdArgs);
printOutput(res);
core.info(`golangci-lint found no issues`);
}
catch (exc) {
// This logging passes issues to GitHub annotations but comments can be more convenient for some users.
printOutput(exc);
if (exc.code === 1) {
core.setFailed(`issues found`);
@ -97541,8 +97568,8 @@ async function runGolangciLint(binPath, rootDir) {
else {
core.setFailed(`golangci-lint exit with code ${exc.code}`);
}
})
.finally(() => core.info(`Ran golangci-lint in ${Date.now() - startedAt}ms`));
}
core.info(`Ran golangci-lint in ${Date.now() - startedAt}ms`);
}
async function runVerify(binPath, userArgsMap, cmdArgs) {
const verify = core.getBooleanInput(`verify`, { required: true });
@ -97558,7 +97585,8 @@ async function runVerify(binPath, userArgsMap, cmdArgs) {
cmdVerify += ` --config=${userArgsMap.get("config")}`;
}
core.info(`Running [${cmdVerify}] in [${cmdArgs.cwd || process.cwd()}] ...`);
await execCommand(cmdVerify, cmdArgs).then(printOutput);
const res = await execShellCommand(cmdVerify, cmdArgs);
printOutput(res);
}
async function getConfigPath(binPath, userArgsMap, cmdArgs) {
let cmdConfigPath = `${binPath} config path`;
@ -97567,73 +97595,22 @@ async function getConfigPath(binPath, userArgsMap, cmdArgs) {
}
core.info(`Running [${cmdConfigPath}] in [${cmdArgs.cwd || process.cwd()}] ...`);
try {
const resPath = await execCommand(cmdConfigPath, cmdArgs);
const resPath = await execShellCommand(cmdConfigPath, cmdArgs);
return resPath.stderr.trim();
}
catch {
return ``;
}
}
async function debugAction(binPath) {
const flags = core.getInput(`debug`).split(`,`);
if (flags.includes(`clean`)) {
const cmd = `${binPath} cache clean`;
core.info(`Running [${cmd}] ...`);
await execCommand(cmd).then(printOutput);
}
if (flags.includes(`cache`)) {
const cmd = `${binPath} cache status`;
core.info(`Running [${cmd}] ...`);
await execCommand(cmd).then(printOutput);
}
}
function getWorkingDirectory() {
const workingDirectory = core.getInput(`working-directory`);
if (workingDirectory) {
if (!fs.existsSync(workingDirectory) || !fs.lstatSync(workingDirectory).isDirectory()) {
throw new Error(`working-directory (${workingDirectory}) was not a path`);
}
}
return workingDirectory;
}
function modulesAutoDetection(rootDir) {
const o = {
cwd: rootDir,
exclude: ["**/vendor/**", "**/node_modules/**", "**/.git/**", "**/dist/**"],
};
const matches = fs.globSync("**/go.mod", o);
const dirs = matches
.filter((m) => typeof m === "string")
.map((m) => path.resolve(rootDir, path.dirname(m)))
.sort();
return [...new Set(dirs)];
}
async function runLint(binPath) {
const workingDirectory = getWorkingDirectory();
const experimental = core.getInput(`experimental`).split(`,`);
if (experimental.includes(`automatic-module-directories`)) {
const wds = modulesAutoDetection(workingDirectory);
const cwd = process.cwd();
for (const wd of wds) {
await core.group(`run golangci-lint in ${path.relative(cwd, wd)}`, () => runGolangciLint(binPath, wd));
}
return;
}
await core.group(`run golangci-lint`, () => runGolangciLint(binPath, workingDirectory));
}
async function run() {
try {
await core.group(`Restore cache`, cache_1.restoreCache);
const binPath = await core.group(`Install`, () => (0, install_1.install)().then(plugins.install));
core.addPath(path.dirname(binPath));
if (core.getInput(`debug`)) {
await core.group(`Debug`, () => debugAction(binPath));
}
const installOnly = core.getBooleanInput(`install-only`, { required: true });
const { binPath, patchPath } = await core.group(`prepare environment`, () => prepareEnv(installOnly));
core.addPath(path.dirname(binPath));
if (installOnly) {
return;
}
await runLint(binPath);
await core.group(`run golangci-lint`, () => runLint(binPath, patchPath));
}
catch (error) {
core.error(`Failed to run: ${error}, ${error.stack}`);
@ -97912,10 +97889,6 @@ const isLessVersion = (a, b) => {
};
const getRequestedVersion = () => {
let requestedVersion = core.getInput(`version`);
let versionFilePath = core.getInput(`version-file`);
if (requestedVersion && versionFilePath) {
core.warning(`Both version (${requestedVersion}) and version-file (${versionFilePath}) inputs are specified, only version will be used`);
}
const workingDirectory = core.getInput(`working-directory`);
let goMod = "go.mod";
if (workingDirectory) {
@ -97929,24 +97902,6 @@ const getRequestedVersion = () => {
core.info(`Found golangci-lint version '${requestedVersion}' in '${goMod}' file`);
}
}
if (requestedVersion == "" && versionFilePath) {
if (workingDirectory) {
versionFilePath = path_1.default.join(workingDirectory, versionFilePath);
}
if (!fs.existsSync(versionFilePath)) {
throw new Error(`The specified golangci-lint version file at: ${versionFilePath} does not exist`);
}
const content = fs.readFileSync(versionFilePath, "utf-8");
if (path_1.default.basename(versionFilePath) === ".tool-versions") {
// asdf/mise file.
const match = content.match(/^golangci-lint\s+([^\n#]+)/m);
requestedVersion = match ? "v" + match[1].trim().replace(/^v/gi, "") : "";
}
else {
// .golangci-lint-version file.
requestedVersion = "v" + content.trim().replace(/^v/gi, "");
}
}
const parsedRequestedVersion = parseVersion(requestedVersion);
if (parsedRequestedVersion == null) {
return null;
@ -102728,7 +102683,7 @@ function composeCollection(CN, ctx, token, props, onError) {
let tag = ctx.schema.tags.find(t => t.tag === tagName && t.collection === expType);
if (!tag) {
const kt = ctx.schema.knownTags[tagName];
if (kt?.collection === expType) {
if (kt && kt.collection === expType) {
ctx.schema.tags.push(Object.assign({}, kt, { default: false }));
tag = kt;
}
@ -103614,7 +103569,7 @@ function resolveBlockSeq({ composeNode, composeEmptyNode }, ctx, bs, onError, ta
});
if (!props.found) {
if (props.anchor || props.tag || value) {
if (value?.type === 'block-seq')
if (value && value.type === 'block-seq')
onError(props.end, 'BAD_INDENT', 'All sequence items must start at the same column');
else
onError(offset, 'MISSING_CHAR', 'Sequence item without - indicator');
@ -103831,7 +103786,7 @@ function resolveFlowCollection({ composeNode, composeEmptyNode }, ctx, fc, onErr
}
}
else if (value) {
if ('source' in value && value.source?.[0] === ':')
if ('source' in value && value.source && value.source[0] === ':')
onError(value, 'MISSING_CHAR', `Missing space after : in ${fcName}`);
else
onError(valueProps.start, 'MISSING_CHAR', `Missing , or : between ${fcName} items`);
@ -103875,7 +103830,7 @@ function resolveFlowCollection({ composeNode, composeEmptyNode }, ctx, fc, onErr
const expectedEnd = isMap ? '}' : ']';
const [ce, ...ee] = fc.end;
let cePos = offset;
if (ce?.source === expectedEnd)
if (ce && ce.source === expectedEnd)
cePos = ce.offset + ce.source.length;
else {
const name = fcName[0].toUpperCase() + fcName.substring(1);
@ -105256,7 +105211,7 @@ const prettifyError = (src, lc) => (error) => {
if (/[^ ]/.test(lineStr)) {
let count = 1;
const end = error.linePos[1];
if (end?.line === line && end.col > col) {
if (end && end.line === line && end.col > col) {
count = Math.max(1, Math.min(end.col - col, 80 - ci));
}
const pointer = ' '.repeat(ci) + '^'.repeat(count);
@ -105424,7 +105379,7 @@ class Alias extends Node.NodeBase {
data = anchors.get(source);
}
/* istanbul ignore if */
if (data?.res === undefined) {
if (!data || data.res === undefined) {
const msg = 'This should not happen: Alias anchor was not resolved?';
throw new ReferenceError(msg);
}
@ -107766,7 +107721,7 @@ class Parser {
}
*step() {
const top = this.peek(1);
if (this.type === 'doc-end' && top?.type !== 'doc-end') {
if (this.type === 'doc-end' && (!top || top.type !== 'doc-end')) {
while (this.stack.length > 0)
yield* this.pop();
this.stack.push({
@ -108298,7 +108253,7 @@ class Parser {
do {
yield* this.pop();
top = this.peek(1);
} while (top?.type === 'flow-collection');
} while (top && top.type === 'flow-collection');
}
else if (fc.end.length === 0) {
switch (this.type) {
@ -110484,7 +110439,7 @@ function stringifyNumber({ format, minFractionDigits, tag, value }) {
const num = typeof value === 'number' ? value : Number(value);
if (!isFinite(num))
return isNaN(num) ? '.nan' : num < 0 ? '-.inf' : '.inf';
let n = Object.is(value, -0) ? '-0' : JSON.stringify(value);
let n = JSON.stringify(value);
if (!format &&
minFractionDigits &&
(!tag || tag === 'tag:yaml.org,2002:float') &&
@ -110615,7 +110570,7 @@ function stringifyPair({ key, value }, ctx, onComment, onChompKeep) {
ws += `\n${stringifyComment.indentComment(cs, ctx.indent)}`;
}
if (valueStr === '' && !ctx.inFlow) {
if (ws === '\n' && valueComment)
if (ws === '\n')
ws = '\n\n';
}
else {

View file

@ -1,3 +0,0 @@
module github.com/golangci/actiona
go 1.24.0

View file

@ -1,3 +0,0 @@
module github.com/golangci/actiona/suba
go 1.24.0

View file

@ -1,26 +0,0 @@
// Package sample is used as test input for golangci action.
package sample
import (
"crypto/md5"
"encoding/hex"
"errors"
)
// Hash~
func Hash(data string) string {
retError()
retError2()
h := md5.New()
h.Write([]byte(data))
return hex.EncodeToString(h.Sum(nil))
}
func retError() error {
return errors.New("err")
}
func retError2() error {
return errors.New("err2")
}

View file

@ -1,3 +0,0 @@
module github.com/golangci/actionb
go 1.24.0

View file

@ -1,26 +0,0 @@
// Package sample is used as test input for golangci action.
package sample
import (
"crypto/md5"
"encoding/hex"
"errors"
)
// Hash~
func Hash(data string) string {
retError()
retError2()
h := md5.New()
h.Write([]byte(data))
return hex.EncodeToString(h.Sum(nil))
}
func retError() error {
return errors.New("err")
}
func retError2() error {
return errors.New("err2")
}

View file

@ -1,3 +0,0 @@
module github.com/golangci/actionc
go 1.24.0

View file

@ -1,26 +0,0 @@
// Package sample is used as test input for golangci action.
package sample
import (
"crypto/md5"
"encoding/hex"
"errors"
)
// Hash~
func Hash(data string) string {
retError()
retError2()
h := md5.New()
h.Write([]byte(data))
return hex.EncodeToString(h.Sum(nil))
}
func retError() error {
return errors.New("err")
}
func retError2() error {
return errors.New("err2")
}

View file

@ -1,26 +0,0 @@
// Package sample is used as test input for golangci action.
package sample
import (
"crypto/md5"
"encoding/hex"
"errors"
)
// Hash~
func Hash(data string) string {
retError()
retError2()
h := md5.New()
h.Write([]byte(data))
return hex.EncodeToString(h.Sum(nil))
}
func retError() error {
return errors.New("err")
}
func retError2() error {
return errors.New("err2")
}

2
go.mod
View file

@ -1,3 +1,3 @@
module github.com/golangci/golangci-lint-action
go 1.24.0
go 1.23

313
package-lock.json generated
View file

@ -16,16 +16,16 @@
"@actions/http-client": "^3.0.0",
"@actions/tool-cache": "^2.0.2",
"@octokit/plugin-retry": "^6.1.0",
"@types/node": "^24.10.1",
"@types/node": "^24.10.0",
"@types/semver": "^7.7.1",
"@types/tmp": "^0.2.6",
"@types/which": "^3.0.4",
"tmp": "^0.2.5",
"which": "^6.0.0",
"yaml": "^2.8.2"
"which": "^5.0.0",
"yaml": "^2.8.1"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^8.48.1",
"@typescript-eslint/eslint-plugin": "^8.46.2",
"@typescript-eslint/parser": "^8.32.1",
"@vercel/ncc": "^0.38.4",
"eslint": "^8.57.1",
@ -33,7 +33,7 @@
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-prettier": "^5.5.4",
"eslint-plugin-simple-import-sort": "^12.1.1",
"prettier": "^3.7.4",
"prettier": "^3.6.2",
"typescript": "^5.9.3"
},
"engines": {
@ -528,7 +528,6 @@
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.0.tgz",
"integrity": "sha512-1LFfa/qnMQvEOAdzlQymH0ulepxbxnCYAKJZfMci/5XJyIHWgEYnDmgnKakbTh7CH2tFQ5O60oYDvns4i9RAIg==",
"peer": true,
"dependencies": {
"@octokit/auth-token": "^4.0.0",
"@octokit/graphql": "^7.1.0",
@ -731,9 +730,9 @@
"dev": true
},
"node_modules/@types/node": {
"version": "24.10.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz",
"integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==",
"version": "24.10.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.0.tgz",
"integrity": "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==",
"license": "MIT",
"dependencies": {
"undici-types": "~7.16.0"
@ -789,17 +788,17 @@
"integrity": "sha512-liyfuo/106JdlgSchJzXEQCVArk0CvevqPote8F8HgWgJ3dRCcTHgJIsLDuee0kxk/mhbInzIZk3QWSZJ8R+2w=="
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.48.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.48.1.tgz",
"integrity": "sha512-X63hI1bxl5ohelzr0LY5coufyl0LJNthld+abwxpCoo6Gq+hSqhKwci7MUWkXo67mzgUK6YFByhmaHmUcuBJmA==",
"version": "8.46.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.2.tgz",
"integrity": "sha512-ZGBMToy857/NIPaaCucIUQgqueOiq7HeAKkhlvqVV4lm089zUFW6ikRySx2v+cAhKeUCPuWVHeimyk6Dw1iY3w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.10.0",
"@typescript-eslint/scope-manager": "8.48.1",
"@typescript-eslint/type-utils": "8.48.1",
"@typescript-eslint/utils": "8.48.1",
"@typescript-eslint/visitor-keys": "8.48.1",
"@typescript-eslint/scope-manager": "8.46.2",
"@typescript-eslint/type-utils": "8.46.2",
"@typescript-eslint/utils": "8.46.2",
"@typescript-eslint/visitor-keys": "8.46.2",
"graphemer": "^1.4.0",
"ignore": "^7.0.0",
"natural-compare": "^1.4.0",
@ -813,7 +812,7 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"@typescript-eslint/parser": "^8.48.1",
"@typescript-eslint/parser": "^8.46.2",
"eslint": "^8.57.0 || ^9.0.0",
"typescript": ">=4.8.4 <6.0.0"
}
@ -829,17 +828,16 @@
}
},
"node_modules/@typescript-eslint/parser": {
"version": "8.48.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.48.1.tgz",
"integrity": "sha512-PC0PDZfJg8sP7cmKe6L3QIL8GZwU5aRvUFedqSIpw3B+QjRSUZeeITC2M5XKeMXEzL6wccN196iy3JLwKNvDVA==",
"version": "8.46.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.2.tgz",
"integrity": "sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.48.1",
"@typescript-eslint/types": "8.48.1",
"@typescript-eslint/typescript-estree": "8.48.1",
"@typescript-eslint/visitor-keys": "8.48.1",
"@typescript-eslint/scope-manager": "8.46.2",
"@typescript-eslint/types": "8.46.2",
"@typescript-eslint/typescript-estree": "8.46.2",
"@typescript-eslint/visitor-keys": "8.46.2",
"debug": "^4.3.4"
},
"engines": {
@ -855,14 +853,14 @@
}
},
"node_modules/@typescript-eslint/project-service": {
"version": "8.48.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.48.1.tgz",
"integrity": "sha512-HQWSicah4s9z2/HifRPQ6b6R7G+SBx64JlFQpgSSHWPKdvCZX57XCbszg/bapbRsOEv42q5tayTYcEFpACcX1w==",
"version": "8.46.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.2.tgz",
"integrity": "sha512-PULOLZ9iqwI7hXcmL4fVfIsBi6AN9YxRc0frbvmg8f+4hQAjQ5GYNKK0DIArNo+rOKmR/iBYwkpBmnIwin4wBg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/tsconfig-utils": "^8.48.1",
"@typescript-eslint/types": "^8.48.1",
"@typescript-eslint/tsconfig-utils": "^8.46.2",
"@typescript-eslint/types": "^8.46.2",
"debug": "^4.3.4"
},
"engines": {
@ -877,14 +875,14 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "8.48.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.48.1.tgz",
"integrity": "sha512-rj4vWQsytQbLxC5Bf4XwZ0/CKd362DkWMUkviT7DCS057SK64D5lH74sSGzhI6PDD2HCEq02xAP9cX68dYyg1w==",
"version": "8.46.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.2.tgz",
"integrity": "sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.48.1",
"@typescript-eslint/visitor-keys": "8.48.1"
"@typescript-eslint/types": "8.46.2",
"@typescript-eslint/visitor-keys": "8.46.2"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -895,9 +893,9 @@
}
},
"node_modules/@typescript-eslint/tsconfig-utils": {
"version": "8.48.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.48.1.tgz",
"integrity": "sha512-k0Jhs4CpEffIBm6wPaCXBAD7jxBtrHjrSgtfCjUvPp9AZ78lXKdTR8fxyZO5y4vWNlOvYXRtngSZNSn+H53Jkw==",
"version": "8.46.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.2.tgz",
"integrity": "sha512-a7QH6fw4S57+F5y2FIxxSDyi5M4UfGF+Jl1bCGd7+L4KsaUY80GsiF/t0UoRFDHAguKlBaACWJRmdrc6Xfkkag==",
"dev": true,
"license": "MIT",
"engines": {
@ -912,15 +910,15 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "8.48.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.48.1.tgz",
"integrity": "sha512-1jEop81a3LrJQLTf/1VfPQdhIY4PlGDBc/i67EVWObrtvcziysbLN3oReexHOM6N3jyXgCrkBsZpqwH0hiDOQg==",
"version": "8.46.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.2.tgz",
"integrity": "sha512-HbPM4LbaAAt/DjxXaG9yiS9brOOz6fabal4uvUmaUYe6l3K1phQDMQKBRUrr06BQkxkvIZVVHttqiybM9nJsLA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.48.1",
"@typescript-eslint/typescript-estree": "8.48.1",
"@typescript-eslint/utils": "8.48.1",
"@typescript-eslint/types": "8.46.2",
"@typescript-eslint/typescript-estree": "8.46.2",
"@typescript-eslint/utils": "8.46.2",
"debug": "^4.3.4",
"ts-api-utils": "^2.1.0"
},
@ -937,9 +935,9 @@
}
},
"node_modules/@typescript-eslint/types": {
"version": "8.48.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.48.1.tgz",
"integrity": "sha512-+fZ3LZNeiELGmimrujsDCT4CRIbq5oXdHe7chLiW8qzqyPMnn1puNstCrMNVAqwcl2FdIxkuJ4tOs/RFDBVc/Q==",
"version": "8.46.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.2.tgz",
"integrity": "sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ==",
"dev": true,
"license": "MIT",
"engines": {
@ -951,20 +949,21 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "8.48.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.48.1.tgz",
"integrity": "sha512-/9wQ4PqaefTK6POVTjJaYS0bynCgzh6ClJHGSBj06XEHjkfylzB+A3qvyaXnErEZSaxhIo4YdyBgq6j4RysxDg==",
"version": "8.46.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.2.tgz",
"integrity": "sha512-f7rW7LJ2b7Uh2EiQ+7sza6RDZnajbNbemn54Ob6fRwQbgcIn+GWfyuHDHRYgRoZu1P4AayVScrRW+YfbTvPQoQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/project-service": "8.48.1",
"@typescript-eslint/tsconfig-utils": "8.48.1",
"@typescript-eslint/types": "8.48.1",
"@typescript-eslint/visitor-keys": "8.48.1",
"@typescript-eslint/project-service": "8.46.2",
"@typescript-eslint/tsconfig-utils": "8.46.2",
"@typescript-eslint/types": "8.46.2",
"@typescript-eslint/visitor-keys": "8.46.2",
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
"minimatch": "^9.0.4",
"semver": "^7.6.0",
"tinyglobby": "^0.2.15",
"ts-api-utils": "^2.1.0"
},
"engines": {
@ -1018,16 +1017,16 @@
}
},
"node_modules/@typescript-eslint/utils": {
"version": "8.48.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.48.1.tgz",
"integrity": "sha512-fAnhLrDjiVfey5wwFRwrweyRlCmdz5ZxXz2G/4cLn0YDLjTapmN4gcCsTBR1N2rWnZSDeWpYtgLDsJt+FpmcwA==",
"version": "8.46.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.2.tgz",
"integrity": "sha512-sExxzucx0Tud5tE0XqR0lT0psBQvEpnpiul9XbGUB1QwpWJJAps1O/Z7hJxLGiZLBKMCutjTzDgmd1muEhBnVg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.7.0",
"@typescript-eslint/scope-manager": "8.48.1",
"@typescript-eslint/types": "8.48.1",
"@typescript-eslint/typescript-estree": "8.48.1"
"@typescript-eslint/scope-manager": "8.46.2",
"@typescript-eslint/types": "8.46.2",
"@typescript-eslint/typescript-estree": "8.46.2"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -1042,13 +1041,13 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "8.48.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.48.1.tgz",
"integrity": "sha512-BmxxndzEWhE4TIEEMBs8lP3MBWN3jFPs/p6gPm/wkv02o41hI6cq9AuSmGAaTTHPtA1FTi2jBre4A9rm5ZmX+Q==",
"version": "8.46.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.2.tgz",
"integrity": "sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.48.1",
"@typescript-eslint/types": "8.46.2",
"eslint-visitor-keys": "^4.2.1"
},
"engines": {
@ -1104,7 +1103,6 @@
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
"integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
"dev": true,
"peer": true,
"bin": {
"acorn": "bin/acorn"
},
@ -1346,6 +1344,19 @@
"concat-map": "0.0.1"
}
},
"node_modules/braces": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"license": "MIT",
"dependencies": {
"fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/call-bind": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
@ -1800,7 +1811,6 @@
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz",
"integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
"dev": true,
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
@ -1857,7 +1867,6 @@
"integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"eslint-config-prettier": "bin/cli.js"
},
@ -2126,6 +2135,36 @@
"integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
"dev": true
},
"node_modules/fast-glob": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
"integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@nodelib/fs.stat": "^2.0.2",
"@nodelib/fs.walk": "^1.2.3",
"glob-parent": "^5.1.2",
"merge2": "^1.3.0",
"micromatch": "^4.0.8"
},
"engines": {
"node": ">=8.6.0"
}
},
"node_modules/fast-glob/node_modules/glob-parent": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
"license": "ISC",
"dependencies": {
"is-glob": "^4.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
@ -2147,24 +2186,6 @@
"reusify": "^1.0.4"
}
},
"node_modules/fdir": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12.0.0"
},
"peerDependencies": {
"picomatch": "^3 || ^4"
},
"peerDependenciesMeta": {
"picomatch": {
"optional": true
}
}
},
"node_modules/file-entry-cache": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
@ -2177,6 +2198,19 @@
"node": "^10.12.0 || >=12.0.0"
}
},
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"license": "MIT",
"dependencies": {
"to-regex-range": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/find-up": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
@ -2797,6 +2831,16 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.12.0"
}
},
"node_modules/is-number-object": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz",
@ -2984,11 +3028,10 @@
}
},
"node_modules/js-yaml": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
"integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"dev": true,
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1"
},
@ -3078,6 +3121,30 @@
"node": ">= 0.4"
}
},
"node_modules/merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 8"
}
},
"node_modules/micromatch": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dev": true,
"license": "MIT",
"dependencies": {
"braces": "^3.0.3",
"picomatch": "^2.3.1"
},
"engines": {
"node": ">=8.6"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
@ -3361,14 +3428,13 @@
"dev": true
},
"node_modules/picomatch": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=12"
"node": ">=8.6"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
@ -3394,12 +3460,10 @@
}
},
"node_modules/prettier": {
"version": "3.7.4",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.7.4.tgz",
"integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==",
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz",
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"prettier": "bin/prettier.cjs"
},
@ -3961,23 +4025,6 @@
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
"dev": true
},
"node_modules/tinyglobby": {
"version": "0.2.15",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
"integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"fdir": "^6.5.0",
"picomatch": "^4.0.3"
},
"engines": {
"node": ">=12.0.0"
},
"funding": {
"url": "https://github.com/sponsors/SuperchupuDev"
}
},
"node_modules/tmp": {
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz",
@ -3987,6 +4034,19 @@
"node": ">=14.14"
}
},
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-number": "^7.0.0"
},
"engines": {
"node": ">=8.0"
}
},
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
@ -4139,7 +4199,6 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@ -4214,10 +4273,9 @@
}
},
"node_modules/which": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/which/-/which-6.0.0.tgz",
"integrity": "sha512-f+gEpIKMR9faW/JgAgPK1D7mekkFoqbmiwvNzuhsHetni20QSgzg9Vhn0g2JSJkkfehQnqdUAx7/e15qS1lPxg==",
"license": "ISC",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz",
"integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==",
"dependencies": {
"isexe": "^3.1.1"
},
@ -4225,7 +4283,7 @@
"node-which": "bin/which.js"
},
"engines": {
"node": "^20.17.0 || >=22.9.0"
"node": "^18.17.0 || >=20.5.0"
}
},
"node_modules/which-boxed-primitive": {
@ -4352,18 +4410,15 @@
}
},
"node_modules/yaml": {
"version": "2.8.2",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz",
"integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==",
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz",
"integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==",
"license": "ISC",
"bin": {
"yaml": "bin.mjs"
},
"engines": {
"node": ">= 14.6"
},
"funding": {
"url": "https://github.com/sponsors/eemeli"
}
},
"node_modules/yocto-queue": {

View file

@ -34,16 +34,16 @@
"@actions/http-client": "^3.0.0",
"@octokit/plugin-retry": "^6.1.0",
"@actions/tool-cache": "^2.0.2",
"@types/node": "^24.10.1",
"@types/node": "^24.10.0",
"@types/semver": "^7.7.1",
"@types/tmp": "^0.2.6",
"@types/which": "^3.0.4",
"tmp": "^0.2.5",
"which": "^6.0.0",
"yaml": "^2.8.2"
"which": "^5.0.0",
"yaml": "^2.8.1"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^8.48.1",
"@typescript-eslint/eslint-plugin": "^8.46.2",
"@typescript-eslint/parser": "^8.32.1",
"@vercel/ncc": "^0.38.4",
"eslint": "^8.57.1",
@ -51,7 +51,7 @@
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-prettier": "^5.5.4",
"eslint-plugin-simple-import-sort": "^12.1.1",
"prettier": "^3.7.4",
"prettier": "^3.6.2",
"typescript": "^5.9.3"
}
}

View file

@ -1,4 +1,4 @@
module github.com/golangci/sample
module sample
go 1.24.0

View file

@ -1,4 +1,4 @@
module github.com/golangci/sample
module sample
go 1.24.0

View file

@ -74,10 +74,7 @@ async function buildCacheKeys(): Promise<string[]> {
}
export async function restoreCache(): Promise<void> {
if (core.getBooleanInput(`skip-cache`, { required: true })) {
core.info(`Skipping cache restoration`)
return
}
if (core.getBooleanInput(`skip-cache`, { required: true })) return
if (!utils.isValidEvent()) {
utils.logWarning(
@ -119,15 +116,8 @@ export async function restoreCache(): Promise<void> {
}
export async function saveCache(): Promise<void> {
if (core.getBooleanInput(`skip-cache`, { required: true })) {
core.info(`Skipping cache saving`)
return
}
if (core.getBooleanInput(`skip-save-cache`, { required: true })) {
core.info(`Skipping cache saving`)
return
}
if (core.getBooleanInput(`skip-cache`, { required: true })) return
if (core.getBooleanInput(`skip-save-cache`, { required: true })) return
// Validate inputs, this can cause task failure
if (!utils.isValidEvent()) {

View file

@ -1,7 +1,6 @@
import * as core from "@actions/core"
import * as tc from "@actions/tool-cache"
import { exec, ExecOptionsWithStringEncoding } from "child_process"
import fs from "fs"
import os from "os"
import path from "path"
import { promisify } from "util"
@ -9,7 +8,7 @@ import which from "which"
import { getVersion, VersionInfo } from "./version"
const execCommand = promisify(exec)
const execShellCommand = promisify(exec)
export enum InstallMode {
Binary = "binary",
@ -22,15 +21,13 @@ type ExecRes = {
stderr: string
}
const printOutput = (res: ExecRes): ExecRes => {
const printOutput = (res: ExecRes): void => {
if (res.stdout) {
core.info(res.stdout)
}
if (res.stderr) {
core.info(res.stderr)
}
return res
}
/**
@ -39,17 +36,6 @@ const printOutput = (res: ExecRes): ExecRes => {
* @returns path to installed binary of golangci-lint.
*/
export async function install(): Promise<string> {
const problemMatchers = core.getBooleanInput(`problem-matchers`)
if (problemMatchers) {
const matchersPath = path.join(__dirname, "../..", "problem-matchers.json")
if (fs.existsSync(matchersPath)) {
// Adds problem matchers.
// https://github.com/actions/setup-go/blob/cdcb36043654635271a94b9a6d1392de5bb323a7/src/main.ts#L81-L83
core.info(`##[add-matcher]${matchersPath}`)
}
}
const mode = core.getInput("install-mode").toLowerCase()
if (mode === InstallMode.None) {
@ -98,14 +84,17 @@ async function goInstall(versionInfo: VersionInfo): Promise<string> {
const options: ExecOptionsWithStringEncoding = { env: { ...process.env, CGO_ENABLED: "1" } }
await execCommand(`go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@${versionInfo.TargetVersion}`, options).then(
printOutput
const exres = await execShellCommand(
`go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@${versionInfo.TargetVersion}`,
options
)
printOutput(exres)
const res = await execCommand(
const res = await execShellCommand(
`go install -n github.com/golangci/golangci-lint/v2/cmd/golangci-lint@${versionInfo.TargetVersion}`,
options
).then(printOutput)
)
printOutput(res)
// The output of `go install -n` when the binary is already installed is `touch <path_to_the_binary>`.
const binPath = res.stderr

View file

@ -17,6 +17,10 @@ export function isOnlyNewIssues(): boolean {
}
export async function fetchPatch(): Promise<string> {
if (!isOnlyNewIssues()) {
return ``
}
const ctx = github.context
switch (ctx.eventName) {
@ -66,7 +70,8 @@ async function fetchPullRequestPatch(ctx: Context): Promise<string> {
}
try {
const patchPath = await createTempDir().then((tempDir) => path.join(tempDir, "pull.patch"))
const tempDir = await createTempDir()
const patchPath = path.join(tempDir, "pull.patch")
core.info(`Writing patch to ${patchPath}`)
await writeFile(patchPath, alterDiffPatch(patch))
return patchPath
@ -103,7 +108,8 @@ async function fetchPushPatch(ctx: Context): Promise<string> {
}
try {
const patchPath = await createTempDir().then((tempDir) => path.join(tempDir, "push.patch"))
const tempDir = await createTempDir()
const patchPath = path.join(tempDir, "push.patch")
core.info(`Writing patch to ${patchPath}`)
await writeFile(patchPath, alterDiffPatch(patch))
return patchPath

View file

@ -5,7 +5,7 @@ import * as path from "path"
import { promisify } from "util"
import YAML from "yaml"
const execCommand = promisify(exec)
const execShellCommand = promisify(exec)
type ExecRes = {
stdout: string
@ -34,13 +34,12 @@ export async function install(binPath: string): Promise<string> {
rootDir = process.cwd()
}
const configFile = ["yml", "yaml", "json"]
.map((ext) => `.custom-gcl.${ext}`)
.map((filename) => path.join(rootDir, filename))
const configFile = [".custom-gcl.yml", ".custom-gcl.yaml", ".custom-gcl.json"]
.map((v) => path.join(rootDir, v))
.find((filePath) => fs.existsSync(filePath))
if (!configFile || configFile === "") {
return binPath
return ""
}
core.info(`Found configuration for the plugin module system : ${configFile}`)
@ -54,7 +53,7 @@ export async function install(binPath: string): Promise<string> {
const v: string = core.getInput(`version`)
if (v !== "" && config.version !== v) {
core.warning(
`The golangci-lint version (${config.version}) defined inside ${configFile} does not match the version defined in the action (${v})`
`The golangci-lint version (${config.version}) defined inside in ${configFile} does not match the version defined in the action (${v})`
)
}
@ -74,15 +73,18 @@ export async function install(binPath: string): Promise<string> {
core.info(`Running [${cmd}] in [${rootDir}] ...`)
const options: ExecOptionsWithStringEncoding = {
cwd: rootDir,
}
try {
const options: ExecOptionsWithStringEncoding = {
cwd: rootDir,
}
return execCommand(cmd, options)
.then(printOutput)
.then(() => core.info(`Built custom golangci-lint binary in ${Date.now() - startedAt}ms`))
.then(() => path.join(rootDir, config.destination, config.name))
.catch((exc) => {
throw new Error(`Failed to build custom golangci-lint binary: ${exc.message}`)
})
const res = await execShellCommand(cmd, options)
printOutput(res)
core.info(`Built custom golangci-lint binary in ${Date.now() - startedAt}ms`)
return path.join(rootDir, config.destination, config.name)
} catch (exc) {
throw new Error(`Failed to build custom golangci-lint binary: ${exc.message}`)
}
}

View file

@ -10,7 +10,37 @@ import { install } from "./install"
import { fetchPatch, isOnlyNewIssues } from "./patch"
import * as plugins from "./plugins"
const execCommand = promisify(exec)
const execShellCommand = promisify(exec)
type Env = {
binPath: string
patchPath: string
}
async function prepareEnv(installOnly: boolean): Promise<Env> {
const startedAt = Date.now()
// Prepare cache, lint and go in parallel.
await restoreCache()
let binPath = await install()
// Build custom golangci-lint if needed.
const customBinPath = await plugins.install(binPath)
if (customBinPath !== "") {
binPath = customBinPath
}
if (installOnly) {
return { binPath, patchPath: `` }
}
const patchPath = await fetchPatch()
core.info(`Prepared env in ${Date.now() - startedAt}ms`)
return { binPath, patchPath }
}
type ExecRes = {
stdout: string
@ -26,7 +56,13 @@ const printOutput = (res: ExecRes): void => {
}
}
async function runGolangciLint(binPath: string, rootDir: string): Promise<void> {
async function runLint(binPath: string, patchPath: string): Promise<void> {
const debug = core.getInput(`debug`)
if (debug.split(`,`).includes(`cache`)) {
const res = await execShellCommand(`${binPath} cache status`)
printOutput(res)
}
const userArgs = core.getInput(`args`)
const addedArgs: string[] = []
@ -41,6 +77,17 @@ async function runGolangciLint(binPath: string, rootDir: string): Promise<void>
const userArgsMap = new Map<string, string>(userArgsList)
const userArgNames = new Set<string>(userArgsList.map(([key]) => key))
const problemMatchers = core.getBooleanInput(`problem-matchers`)
if (problemMatchers) {
const matchersPath = path.join(__dirname, "../..", "problem-matchers.json")
if (fs.existsSync(matchersPath)) {
// Adds problem matchers.
// https://github.com/actions/setup-go/blob/cdcb36043654635271a94b9a6d1392de5bb323a7/src/main.ts#L81-L83
core.info(`##[add-matcher]${matchersPath}`)
}
}
if (isOnlyNewIssues()) {
if (
userArgNames.has(`new`) ||
@ -52,7 +99,6 @@ async function runGolangciLint(binPath: string, rootDir: string): Promise<void>
}
const ctx = github.context
const patchPath = await fetchPatch()
core.info(`only new issues on ${ctx.eventName}: ${patchPath}`)
@ -84,12 +130,17 @@ async function runGolangciLint(binPath: string, rootDir: string): Promise<void>
const cmdArgs: ExecOptionsWithStringEncoding = {}
if (rootDir) {
const workingDirectory = core.getInput(`working-directory`)
if (workingDirectory) {
if (!fs.existsSync(workingDirectory) || !fs.lstatSync(workingDirectory).isDirectory()) {
throw new Error(`working-directory (${workingDirectory}) was not a path`)
}
if (!userArgNames.has(`path-prefix`) && !userArgNames.has(`path-mode`)) {
addedArgs.push(`--path-mode=abs`)
}
cmdArgs.cwd = path.resolve(rootDir)
cmdArgs.cwd = path.resolve(workingDirectory)
}
await runVerify(binPath, userArgsMap, cmdArgs)
@ -99,21 +150,22 @@ async function runGolangciLint(binPath: string, rootDir: string): Promise<void>
core.info(`Running [${cmd}] in [${cmdArgs.cwd || process.cwd()}] ...`)
const startedAt = Date.now()
try {
const res = await execShellCommand(cmd, cmdArgs)
printOutput(res)
core.info(`golangci-lint found no issues`)
} catch (exc) {
// This logging passes issues to GitHub annotations but comments can be more convenient for some users.
printOutput(exc)
return execCommand(cmd, cmdArgs)
.then(printOutput)
.then(() => core.info(`golangci-lint found no issues`))
.catch((exc) => {
// This logging passes issues to GitHub annotations.
printOutput(exc)
if (exc.code === 1) {
core.setFailed(`issues found`)
} else {
core.setFailed(`golangci-lint exit with code ${exc.code}`)
}
}
if (exc.code === 1) {
core.setFailed(`issues found`)
} else {
core.setFailed(`golangci-lint exit with code ${exc.code}`)
}
})
.finally(() => core.info(`Ran golangci-lint in ${Date.now() - startedAt}ms`))
core.info(`Ran golangci-lint in ${Date.now() - startedAt}ms`)
}
async function runVerify(binPath: string, userArgsMap: Map<string, string>, cmdArgs: ExecOptionsWithStringEncoding): Promise<void> {
@ -134,7 +186,8 @@ async function runVerify(binPath: string, userArgsMap: Map<string, string>, cmdA
core.info(`Running [${cmdVerify}] in [${cmdArgs.cwd || process.cwd()}] ...`)
await execCommand(cmdVerify, cmdArgs).then(printOutput)
const res = await execShellCommand(cmdVerify, cmdArgs)
printOutput(res)
}
async function getConfigPath(binPath: string, userArgsMap: Map<string, string>, cmdArgs: ExecOptionsWithStringEncoding): Promise<string> {
@ -146,98 +199,26 @@ async function getConfigPath(binPath: string, userArgsMap: Map<string, string>,
core.info(`Running [${cmdConfigPath}] in [${cmdArgs.cwd || process.cwd()}] ...`)
try {
const resPath = await execCommand(cmdConfigPath, cmdArgs)
const resPath = await execShellCommand(cmdConfigPath, cmdArgs)
return resPath.stderr.trim()
} catch {
return ``
}
}
async function debugAction(binPath: string) {
const flags = core.getInput(`debug`).split(`,`)
if (flags.includes(`clean`)) {
const cmd = `${binPath} cache clean`
core.info(`Running [${cmd}] ...`)
await execCommand(cmd).then(printOutput)
}
if (flags.includes(`cache`)) {
const cmd = `${binPath} cache status`
core.info(`Running [${cmd}] ...`)
await execCommand(cmd).then(printOutput)
}
}
function getWorkingDirectory(): string {
const workingDirectory = core.getInput(`working-directory`)
if (workingDirectory) {
if (!fs.existsSync(workingDirectory) || !fs.lstatSync(workingDirectory).isDirectory()) {
throw new Error(`working-directory (${workingDirectory}) was not a path`)
}
}
return workingDirectory
}
function modulesAutoDetection(rootDir: string): string[] {
const o: fs.GlobOptions = {
cwd: rootDir,
exclude: ["**/vendor/**", "**/node_modules/**", "**/.git/**", "**/dist/**"],
}
const matches = fs.globSync("**/go.mod", o)
const dirs = matches
.filter((m) => typeof m === "string")
.map((m) => path.resolve(rootDir, path.dirname(m)))
.sort()
return [...new Set(dirs)]
}
async function runLint(binPath: string): Promise<void> {
const workingDirectory = getWorkingDirectory()
const experimental = core.getInput(`experimental`).split(`,`)
if (experimental.includes(`automatic-module-directories`)) {
const wds = modulesAutoDetection(workingDirectory)
const cwd = process.cwd()
for (const wd of wds) {
await core.group(`run golangci-lint in ${path.relative(cwd, wd)}`, () => runGolangciLint(binPath, wd))
}
return
}
await core.group(`run golangci-lint`, () => runGolangciLint(binPath, workingDirectory))
}
export async function run(): Promise<void> {
try {
await core.group(`Restore cache`, restoreCache)
const installOnly = core.getBooleanInput(`install-only`, { required: true })
const binPath = await core.group(`Install`, () => install().then(plugins.install))
const { binPath, patchPath } = await core.group(`prepare environment`, () => prepareEnv(installOnly))
core.addPath(path.dirname(binPath))
if (core.getInput(`debug`)) {
await core.group(`Debug`, () => debugAction(binPath))
}
const installOnly = core.getBooleanInput(`install-only`, { required: true })
if (installOnly) {
return
}
await runLint(binPath)
await core.group(`run golangci-lint`, () => runLint(binPath, patchPath))
} catch (error) {
core.error(`Failed to run: ${error}, ${error.stack}`)
core.setFailed(error.message)

View file

@ -67,12 +67,6 @@ const isLessVersion = (a: Version, b: Version): boolean => {
const getRequestedVersion = (): Version => {
let requestedVersion = core.getInput(`version`)
let versionFilePath = core.getInput(`version-file`)
if (requestedVersion && versionFilePath) {
core.warning(`Both version (${requestedVersion}) and version-file (${versionFilePath}) inputs are specified, only version will be used`)
}
const workingDirectory = core.getInput(`working-directory`)
let goMod = "go.mod"
@ -89,27 +83,6 @@ const getRequestedVersion = (): Version => {
}
}
if (requestedVersion == "" && versionFilePath) {
if (workingDirectory) {
versionFilePath = path.join(workingDirectory, versionFilePath)
}
if (!fs.existsSync(versionFilePath)) {
throw new Error(`The specified golangci-lint version file at: ${versionFilePath} does not exist`)
}
const content = fs.readFileSync(versionFilePath, "utf-8")
if (path.basename(versionFilePath) === ".tool-versions") {
// asdf/mise file.
const match = content.match(/^golangci-lint\s+([^\n#]+)/m)
requestedVersion = match ? "v" + match[1].trim().replace(/^v/gi, "") : ""
} else {
// .golangci-lint-version file.
requestedVersion = "v" + content.trim().replace(/^v/gi, "")
}
}
const parsedRequestedVersion = parseVersion(requestedVersion)
if (parsedRequestedVersion == null) {
return null