diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 92194f6ec..b042dfce5 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -7,7 +7,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
- go: ['1.19', '1.20']
+ go: ['1.20', '1.21']
runs-on: ${{ matrix.os }}
steps:
- name: Install dependencies on macOS
@@ -34,16 +34,19 @@ jobs:
pip install pyflakes
pyflakes --version
if: ${{ matrix.os == 'windows-latest' }}
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: actions/setup-go@v4
with:
go-version: ${{ matrix.go }}
+ - run: go test -v -race -coverprofile coverage.txt -covermode=atomic ./...
+ - run: go tool cover -func ./coverage.txt
+ # Check build without CGO
- run: go build ./cmd/actionlint
env:
# Note: -race requires cgo
CGO_ENABLED: 0
- - run: go test -v -race -coverprofile coverage.txt -covermode=atomic ./...
- - run: go tool cover -func ./coverage.txt
+ # Set -race for catching data races on dog fooding (#333)
+ - run: go build -race ./cmd/actionlint
- name: Dog fooding 🐶
run: |
echo "::add-matcher::.github/actionlint-matcher.json"
@@ -57,10 +60,10 @@ jobs:
name: Wasm
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: actions/setup-go@v4
with:
- go-version: '1.20'
+ go-version: '1.21'
- uses: actions/setup-node@v3
with:
node-version: "lts/*"
@@ -79,10 +82,10 @@ jobs:
name: Lint
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: actions/setup-go@v4
with:
- go-version: '1.20'
+ go-version: '1.21'
- name: Check Go sources are formatted
run: |
diffs="$(gofmt -d ./*.go ./cmd/actionlint/*.go ./scripts/*/*.go ./playground/*.go)"
@@ -101,13 +104,13 @@ jobs:
name: Dockerfile
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Build image
id: image
uses: docker/build-push-action@v3
with:
build-args: |
- GOLANG_VER=1.20
+ GOLANG_VER=1.21
push: false
- name: Test Docker image
run: docker container run
diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml
index fc09daf8e..ea67ba73c 100644
--- a/.github/workflows/codeql.yaml
+++ b/.github/workflows/codeql.yaml
@@ -28,7 +28,7 @@ jobs:
matrix:
language: ['go', 'javascript']
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: github/codeql-action/init@v2
with:
config-file: ./.github/codeql/codeql-config.yaml
@@ -37,7 +37,7 @@ jobs:
if: ${{ matrix.language != 'go' }}
- uses: actions/setup-go@v4
with:
- go-version: '1.20'
+ go-version: '1.21'
if: ${{ matrix.language == 'go' }}
- name: Build Go sources
run: |
diff --git a/.github/workflows/download.yaml b/.github/workflows/download.yaml
index 9b517a9a9..3bce86dfe 100644
--- a/.github/workflows/download.yaml
+++ b/.github/workflows/download.yaml
@@ -18,6 +18,6 @@ jobs:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- run: ./scripts/test-download-actionlint.bash
shell: bash
diff --git a/.github/workflows/generate.yaml b/.github/workflows/generate.yaml
index f086e046a..70c79e495 100644
--- a/.github/workflows/generate.yaml
+++ b/.github/workflows/generate.yaml
@@ -20,10 +20,10 @@ jobs:
contents: write
pull-requests: write
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: actions/setup-go@v4
with:
- go-version: '1.20'
+ go-version: '1.21'
- name: Check new release on GitHub
run: go run ./scripts/generate-popular-actions -d
- run: go generate
diff --git a/.github/workflows/matcher.yaml b/.github/workflows/matcher.yaml
index 4743604df..09cf3cb63 100644
--- a/.github/workflows/matcher.yaml
+++ b/.github/workflows/matcher.yaml
@@ -16,10 +16,10 @@ jobs:
name: Test generate-actionlint-matcher
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: actions/setup-go@v4
with:
- go-version: '1.20'
+ go-version: '1.21'
- uses: actions/setup-node@v3
with:
node-version: "lts/*"
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index ef8bd8561..75f803e42 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -11,7 +11,7 @@ jobs:
release:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
ruby-version: '3.0'
@@ -19,7 +19,7 @@ jobs:
- run: ronn ./man/actionlint.1.ronn
- uses: actions/setup-go@v4
with:
- go-version: '1.20'
+ go-version: '1.21'
- uses: goreleaser/goreleaser-action@v4
with:
version: latest
@@ -29,7 +29,7 @@ jobs:
- name: Post-release download check
run: bash ./scripts/download-actionlint.bash "${GITHUB_REF#refs/tags/v}"
- name: Clone nested repository to make version bump commit
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
path: ./tmp-actionlint-for-update-ver
ref: main
@@ -57,7 +57,7 @@ jobs:
docker:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Get tag name
id: tag
run: |
@@ -77,7 +77,7 @@ jobs:
with:
platforms: linux/amd64,linux/arm64
build-args: |
- GOLANG_VER=1.20
+ GOLANG_VER=1.21
ACTIONLINT_VER=${{ steps.tag.outputs.name }}
push: true
tags: |
diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml
index 0376757e0..b6abfd3da 100644
--- a/.pre-commit-hooks.yaml
+++ b/.pre-commit-hooks.yaml
@@ -13,7 +13,7 @@
language: docker_image
types: ["yaml"]
files: ^\.github/workflows/
- entry: rhysd/actionlint:1.6.25
+ entry: rhysd/actionlint:1.6.26
- id: actionlint-system
name: Lint GitHub Actions workflow files
description: Runs system-installed actionlint to lint GitHub Actions workflow files
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b295f1917..e37dccdb2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,99 @@
+
+# [v1.6.26](https://github.com/rhysd/actionlint/releases/tag/v1.6.26) - 18 Sep 2023
+
+- Several template fields and template actions were added. All fields and actions are listed in [the document](https://github.com/rhysd/actionlint/blob/main/docs/usage.md#format-error-messages). Please read it for more details. ([#311](https://github.com/rhysd/actionlint/issues/311))
+ - By these additions, now actionlint can output the result in [the SARIF format](https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html). SARIF is a format for the output of static analysis tools used by [GitHub CodeQL](https://codeql.github.com/). [the example Go template](https://github.com/rhysd/actionlint/blob/main/testdata/format/sarif_template.txt) to format actionlint output in SARIF.
+ ```sh
+ actionlint -format "$(cat /path/to/sarif_template.txt)" > output.json
+ ```
+ - `allKinds` returns the kinds (lint rules) information as an array. You can include what lint rules are defined in the command output.
+ - `toPascalCase` converts snake case (`foo_bar`) or kebab case (`foo-bar`) into pascal case (`FooBar`).
+- Report an error when the condition at `if:` is always evaluated to true. See [the check document](https://github.com/rhysd/actionlint/blob/main/docs/checks.md#if-cond-always-true) to know more details. ([#272](https://github.com/rhysd/actionlint/issues/272))
+ ```yaml
+ # ERROR: All the following `if:` conditions are always evaluated to true
+ - run: echo 'Commit is pushed'
+ if: |
+ ${{ github.event_name == 'push' }}
+ - run: echo 'Commit is pushed'
+ if: "${{ github.event_name == 'push' }} "
+ - run: echo 'Commit is pushed to main'
+ if: ${{ github.event_name == 'push' }} && ${{ github.ref_name == 'main' }}
+ ```
+- Fix actionlint didn't understand `${{ }}` placeholders in environment variable names. ([#312](https://github.com/rhysd/actionlint/issues/312))
+ ```yaml
+ env:
+ "${{ steps.x.outputs.value }}": "..."
+ ```
+- Fix type of matrix row when some expression is assigned to it with `${{ }}` ([#285](https://github.com/rhysd/actionlint/issues/285))
+ ```yaml
+ strategy:
+ matrix:
+ test:
+ # Matrix rows are assigned from JSON string
+ - ${{ fromJson(inputs.matrix) }}
+ steps:
+ - run: echo ${{ matrix.test.foo.bar }}
+ ```
+- Fix checking `exclude` of matrix was incorrect when some matrix row is dynamically constructed with `${{ }}`. ([#261](https://github.com/rhysd/actionlint/issues/261))
+ ```yaml
+ strategy:
+ matrix:
+ build-type:
+ - debug
+ - ${{ fromJson(inputs.custom-build-type) }}
+ exclude:
+ # 'release' is not listed in 'build-type' row, but it should not be reported as error
+ # since the second row of 'build-type' is dynamically constructed with ${{ }}.
+ - build-type: release
+ ```
+- Fix checking `exclude` of matrix was incorrect when object is nested at row of the matrix. ([#249](https://github.com/rhysd/actionlint/issues/249))
+ ```yaml
+ matrix:
+ os:
+ - name: Ubuntu
+ matrix: ubuntu
+ - name: Windows
+ matrix: windows
+ arch:
+ - name: ARM
+ matrix: arm
+ - name: Intel
+ matrix: intel
+ exclude:
+ # This should exclude { os: { name: Windows, matrix: windows }, arch: {name: ARM, matrix: arm } }
+ - os:
+ matrix: windows
+ arch:
+ matrix: arm
+ ```
+- Fix data race when `actionlint.yml` config file is used by multiple goroutines to check multiple workflow files. ([#333](https://github.com/rhysd/actionlint/issues/333))
+- Check keys' case sensitivity. ([#302](https://github.com/rhysd/actionlint/issues/302))
+ ```yaml
+ steps:
+ # ERROR: 'run:' is correct
+ - ruN: echo "hello"
+ ```
+- Add `number` as [input type of `workflow_dispatch` event](https://docs.github.com/en/actions/learn-github-actions/contexts#inputs-context). ([#316](https://github.com/rhysd/actionlint/issues/316))
+- Check max number of inputs of `workflow_dispatch` event is 10.
+- Check numbers at `timeout-minutes` and `max-parallel` are greater than zero.
+- Add Go APIs to define a custom rule. Please read [the code example](https://pkg.go.dev/github.com/rhysd/actionlint/#example_Linter_yourOwnRule) to know the usage.
+ - Make some [`RuleBase`](https://pkg.go.dev/github.com/rhysd/actionlint#RuleBase) methods public which are useful to implement your own custom rule type. (thanks [@hugo-syn](https://github.com/hugo-syn), [#327](https://github.com/rhysd/actionlint/issues/327), [#331](https://github.com/rhysd/actionlint/issues/331))
+ - `OnRulesCreated` field is added to [`LinterOptions`](https://pkg.go.dev/github.com/rhysd/actionlint#LinterOptions) struct. You can modify applied rules with the hook (add your own rule, remove some rule, ...).
+- Add `NewProject()` Go API to create a [`Project`](https://pkg.go.dev/github.com/rhysd/actionlint#Project) instance.
+- Fix tests failed when sources are downloaded from `.tar.gz` link. ([#307](https://github.com/rhysd/actionlint/issues/307))
+- Improve [the pre-commit document](https://github.com/rhysd/actionlint/blob/main/docs/usage.md#pre-commit) to explain all pre-commit hooks by this repository.
+- Clarify the regular expression syntax of `-ignore` option is [RE2](https://github.com/google/re2/wiki/Syntax). ([#320](https://github.com/rhysd/actionlint/issues/320))
+- Use ubuntu-latest runner to create winget release. (thanks [@sitiom](https://github.com/sitiom), [#308](https://github.com/rhysd/actionlint/issues/308))
+- Update popular actions data set, available contexts, webhook types to the latest.
+ - Fix typo in `watch` webhook's types (thanks [@suzuki-shunsuke](https://github.com/suzuki-shunsuke), [#334](https://github.com/rhysd/actionlint/issues/334))
+ - Add `secret_source` property to [`github` context](https://docs.github.com/en/actions/learn-github-actions/contexts#github-context). (thanks [@asml-mdroogle](https://github.com/asml-mdroogle), [#339](https://github.com/rhysd/actionlint/issues/339))
+ - Many new major releases are added to the popular actions data set (including `actions/checkout@v4`).
+- Use Go 1.21 to build release binaries.
+- Update Go dependencies to the latest. (thanks [@harryzcy](https://github.com/harryzcy), [#322](https://github.com/rhysd/actionlint/issues/322))
+
+[Changes][v1.6.26]
+
+
# [v1.6.25](https://github.com/rhysd/actionlint/releases/tag/v1.6.25) - 15 Jun 2023
@@ -9,14 +105,14 @@
```
- Add support for macOS XL runners. `macos-latest-xl`, `macos-13-xl`, `macos-12-xl` labels are available at `runs-on:`. ([#299](https://github.com/rhysd/actionlint/issues/299), thanks [@woa7](https://github.com/woa7))
- Find Git project directory from `-stdin-filename` command line argument. Even if the workflow content is passed via stdin, actionlint can recognize reusable workflows depended by the workflow using file path passed at `-stdin-filename` argument. ([#283](https://github.com/rhysd/actionlint/issues/283))
-- Fix order of errors is not deterministic when multiple errors happens at the same location (file name, line number, column number) when building actionlint with Go 1.20.
+- Fix order of errors is not deterministic when multiple errors happen at the same location (file name, line number, column number). It happens only when building actionlint with Go 1.20 or later.
- Fix type name of `watch` webhook.
- Fix type of matrix row (property of `matrix` context) when `${{ }}` is used in the row value. ([#294](https://github.com/rhysd/actionlint/issues/294))
- Fix `go install ./...` doesn't work. ([#297](https://github.com/rhysd/actionlint/issues/297))
-- Update `actionlint` pre-commit hook to use Go toolchain. Now pre-commit automatically installs `actionlint` command so you don't need to install it manually. Note that this hook requires pre-commit v3.0.0 or later. For those who don't have Go toolchain, the previous hook is maintained as `actionlint-system` hook. ([#301](https://github.com/rhysd/actionlint/issues/301), thanks [@Freed-Wu](https://github.com/Freed-Wu) and [@dokempf](https://github.com/dokempf))
+- Update `actionlint` pre-commit hook to use Go toolchain. Now pre-commit automatically installs `actionlint` command so you don't need to install it manually. Note that this hook requires pre-commit v3.0.0 or later. For those who don't have Go toolchain, the previous hook is maintained as `actionlint-system` hook. Please read [the document](https://github.com/rhysd/actionlint/blob/main/docs/usage.md#pre-commit) to know the usage details. ([#301](https://github.com/rhysd/actionlint/issues/301), thanks [@Freed-Wu](https://github.com/Freed-Wu) and [@dokempf](https://github.com/dokempf))
- Update Go dependencies to the latest.
- Update npm dependencies for playground to the latest and fix optimizing Wasm binary with `wasm-opt`.
-- Update popular actions data set. New major versions and new inputs of many popular actions are now supported like `sparse-checkout` of `actions/checkout`. ([#305](https://github.com/rhysd/actionlint/issues/305))
+- Update popular actions data set. New major versions and new inputs of many popular actions are now supported like `sparse-checkout` input of `actions/checkout` action. ([#305](https://github.com/rhysd/actionlint/issues/305))
- Fix outdated document for Problem Matchers. ([#289](https://github.com/rhysd/actionlint/issues/289), thanks [@carlcsaposs-canonical](https://github.com/carlcsaposs-canonical))
- Fix outdated links in document for super-linter. ([#303](https://github.com/rhysd/actionlint/issues/303), thanks [@gmacario](https://github.com/gmacario))
- Automate releasing the Winget package with GitHub Actions. ([#276](https://github.com/rhysd/actionlint/issues/276), [#293](https://github.com/rhysd/actionlint/issues/293), thanks [@sitiom](https://github.com/sitiom))
@@ -1402,6 +1498,7 @@ See documentation for more details:
[Changes][v1.0.0]
+[v1.6.26]: https://github.com/rhysd/actionlint/compare/v1.6.25...v1.6.26
[v1.6.25]: https://github.com/rhysd/actionlint/compare/v1.6.24...v1.6.25
[v1.6.24]: https://github.com/rhysd/actionlint/compare/v1.6.23...v1.6.24
[v1.6.23]: https://github.com/rhysd/actionlint/compare/v1.6.22...v1.6.23
diff --git a/HomebrewFormula/actionlint.rb b/HomebrewFormula/actionlint.rb
index 4e62e1c15..603990152 100644
--- a/HomebrewFormula/actionlint.rb
+++ b/HomebrewFormula/actionlint.rb
@@ -5,22 +5,22 @@
class Actionlint < Formula
desc "Static checker for GitHub Actions workflow files"
homepage "https://github.com/rhysd/actionlint#readme"
- version "1.6.25"
+ version "1.6.26"
license "MIT"
on_macos do
- if Hardware::CPU.intel?
- url "https://github.com/rhysd/actionlint/releases/download/v1.6.25/actionlint_1.6.25_darwin_amd64.tar.gz"
- sha256 "30d69622ff9fbf564081515bf7d20538f2cb590150ef0c69fdcc56fa23fe85f1"
+ if Hardware::CPU.arm?
+ url "https://github.com/rhysd/actionlint/releases/download/v1.6.26/actionlint_1.6.26_darwin_arm64.tar.gz"
+ sha256 "5e131ab7de7ad051e1923b80d167aaa414734e97c720698c48778250e1dd2590"
def install
bin.install "actionlint"
man1.install "man/actionlint.1"
end
end
- if Hardware::CPU.arm?
- url "https://github.com/rhysd/actionlint/releases/download/v1.6.25/actionlint_1.6.25_darwin_arm64.tar.gz"
- sha256 "9153ebe7be2a33c9047e60aeb0d8d7b831b22fe99bbea63d365500c68245d6df"
+ if Hardware::CPU.intel?
+ url "https://github.com/rhysd/actionlint/releases/download/v1.6.26/actionlint_1.6.26_darwin_amd64.tar.gz"
+ sha256 "bfa890e77a8508603c785af09a30bbab3a3255d291d8d27efc3f20ac8e303a8e"
def install
bin.install "actionlint"
@@ -31,26 +31,26 @@ def install
on_linux do
if Hardware::CPU.arm? && !Hardware::CPU.is_64_bit?
- url "https://github.com/rhysd/actionlint/releases/download/v1.6.25/actionlint_1.6.25_linux_armv6.tar.gz"
- sha256 "79180b0d572a4154965c0bcdb3ab3a37ca24b6d254192932ec7ca39128ceac5a"
+ url "https://github.com/rhysd/actionlint/releases/download/v1.6.26/actionlint_1.6.26_linux_armv6.tar.gz"
+ sha256 "1d6a1686ba14257d78131806d961ca79e599fd5fcfa09e6bdc1084a8ae7160ae"
def install
bin.install "actionlint"
man1.install "man/actionlint.1"
end
end
- if Hardware::CPU.intel?
- url "https://github.com/rhysd/actionlint/releases/download/v1.6.25/actionlint_1.6.25_linux_amd64.tar.gz"
- sha256 "80a54660e73ad55a0818372bdaa0dced82eb86f618e6bf1621e73f099e61c027"
+ if Hardware::CPU.arm? && Hardware::CPU.is_64_bit?
+ url "https://github.com/rhysd/actionlint/releases/download/v1.6.26/actionlint_1.6.26_linux_arm64.tar.gz"
+ sha256 "a1056d85d614af4f6e5517ed2911dab2621b8e97c368c8b265328f9c22801648"
def install
bin.install "actionlint"
man1.install "man/actionlint.1"
end
end
- if Hardware::CPU.arm? && Hardware::CPU.is_64_bit?
- url "https://github.com/rhysd/actionlint/releases/download/v1.6.25/actionlint_1.6.25_linux_arm64.tar.gz"
- sha256 "8bedeea8ed636891fd7351fa7ccbc75fdb5bee6efde5320162f712e8457e73ea"
+ if Hardware::CPU.intel?
+ url "https://github.com/rhysd/actionlint/releases/download/v1.6.26/actionlint_1.6.26_linux_amd64.tar.gz"
+ sha256 "f0294c342af98fad4ff917bc32032f28e1b55f76aedf291886ec10bbed7c12e1"
def install
bin.install "actionlint"
diff --git a/Makefile b/Makefile
index a85130cac..da760f40c 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,15 @@
SRCS := $(filter-out %_test.go, $(wildcard *.go cmd/actionlint/*.go)) go.mod go.sum
TESTS := $(filter %_test.go, $(wildcard *.go))
-TOOL := $(wildcard scripts/*/*.go)
-TESTDATA := $(wildcard testdata/examples/* testdata/err/* testdata/ok/*)
-GOTEST := $(shell command -v gotest 2>/dev/null)
+TOOL := $(filter %_test.go, $(wildcard scripts/*/*.go))
+TESTDATA := $(wildcard \
+ testdata/examples/* \
+ testdata/err/* \
+ testdata/ok/* \
+ testdata/config/* \
+ testdata/format/* \
+ testdata/projects/* \
+ testdata/reusable_workflow_metadata/* \
+ )
all: clean build test
@@ -10,14 +17,14 @@ all: clean build test
go test ./...
touch .testtimestamp
-test: .testtimestamp
+t test: .testtimestamp
.staticchecktimestamp: $(TESTS) $(SRCS) $(TOOL)
staticcheck ./...
GOOS=js GOARCH=wasm staticcheck ./playground
touch .staticchecktimestamp
-lint: .staticchecktimestamp
+l lint: .staticchecktimestamp
popular_actions.go all_webhooks.go availability.go: scripts/generate-popular-actions/main.go scripts/generate-webhook-events/main.go scripts/generate-availability/main.go
ifdef SKIP_GO_GENERATE
@@ -29,7 +36,7 @@ endif
actionlint: $(SRCS) popular_actions.go all_webhooks.go
CGO_ENABLED=0 go build ./cmd/actionlint
-build: actionlint
+b build: actionlint
actionlint_fuzz-fuzz.zip:
go-fuzz-build ./fuzz
@@ -55,13 +62,8 @@ scripts/generate-actionlint-matcher/test/no_escape.txt: actionlint
scripts/generate-actionlint-matcher/test/want.json: actionlint
./actionlint -format '{{json .}}' ./testdata/err/one_error.yaml > scripts/generate-actionlint-matcher/test/want.json || true
-clean:
+c clean:
rm -f ./actionlint ./.testtimestamp ./.staticchecktimestamp ./actionlint_fuzz-fuzz.zip ./man/actionlint.1 ./man/actionlint.1.html ./actionlint-workflow-ast
rm -rf ./corpus ./crashers
-b: build
-t: test
-c: clean
-l: lint
-
.PHONY: all test clean build lint fuzz man bench b t c l
diff --git a/all_webhooks.go b/all_webhooks.go
index 95cac9a17..13a79afe7 100644
--- a/all_webhooks.go
+++ b/all_webhooks.go
@@ -36,7 +36,7 @@ var AllWebhookTypes = map[string][]string{
"release": {"published", "unpublished", "created", "edited", "deleted", "prereleased", "released"},
"repository_dispatch": {},
"status": {},
- "watch": {"starred"},
+ "watch": {"started"},
"workflow_dispatch": {},
"workflow_run": {"completed", "requested", "in_progress"},
}
diff --git a/config.go b/config.go
index cadd3fc02..0a9821fa7 100644
--- a/config.go
+++ b/config.go
@@ -3,6 +3,7 @@ package actionlint
import (
"fmt"
"os"
+ "path/filepath"
"strings"
"gopkg.in/yaml.v3"
@@ -41,6 +42,24 @@ func ReadConfigFile(path string) (*Config, error) {
return parseConfig(b, path)
}
+// loadRepoConfig reads config file from the repository's .github/actionlint.yml or
+// .github/actionlint.yaml.
+func loadRepoConfig(root string) (*Config, error) {
+ for _, f := range []string{"actionlint.yaml", "actionlint.yml"} {
+ path := filepath.Join(root, ".github", f)
+ b, err := os.ReadFile(path)
+ if err != nil {
+ continue // file does not exist
+ }
+ cfg, err := parseConfig(b, path)
+ if err != nil {
+ return nil, err
+ }
+ return cfg, nil
+ }
+ return nil, nil
+}
+
func writeDefaultConfigFile(path string) error {
b := []byte(`self-hosted-runner:
# Labels of self-hosted runner in array of strings.
diff --git a/expr_sema.go b/expr_sema.go
index 5a872411c..0f1af1389 100644
--- a/expr_sema.go
+++ b/expr_sema.go
@@ -225,6 +225,7 @@ var BuiltinGlobalVariableTypes = map[string]ExprType{
"run_id": StringType{},
"run_number": StringType{},
"run_attempt": StringType{},
+ "secret_source": StringType{},
"server_url": StringType{},
"sha": StringType{},
"token": StringType{},
diff --git a/go.mod b/go.mod
index 2b28cc262..4a61a17ff 100644
--- a/go.mod
+++ b/go.mod
@@ -6,11 +6,11 @@ require (
github.com/fatih/color v1.15.0
github.com/google/go-cmp v0.5.9
github.com/mattn/go-colorable v0.1.13
- github.com/mattn/go-runewidth v0.0.14
+ github.com/mattn/go-runewidth v0.0.15
github.com/robfig/cron/v3 v3.0.1
- github.com/yuin/goldmark v1.5.4
+ github.com/yuin/goldmark v1.5.6
golang.org/x/sync v0.3.0
- golang.org/x/sys v0.10.0
+ golang.org/x/sys v0.12.0
gopkg.in/yaml.v3 v3.0.1
)
diff --git a/go.sum b/go.sum
index fe141a9b7..23457014c 100644
--- a/go.sum
+++ b/go.sum
@@ -8,21 +8,21 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
-github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
-github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
+github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
+github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
-github.com/yuin/goldmark v1.5.4 h1:2uY/xC0roWy8IBEGLgB1ywIoEJFGmRrX21YQcvGZzjU=
-github.com/yuin/goldmark v1.5.4/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+github.com/yuin/goldmark v1.5.6 h1:COmQAWTCcGetChm3Ig7G/t8AFAN00t+o8Mt4cf7JpwA=
+github.com/yuin/goldmark v1.5.6/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
-golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
+golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
diff --git a/linter.go b/linter.go
index b1fdea0e2..9894a6dea 100644
--- a/linter.go
+++ b/linter.go
@@ -216,7 +216,10 @@ func (l *Linter) debugWriter() io.Writer {
func (l *Linter) GenerateDefaultConfig(dir string) error {
l.log("Generating default actionlint.yaml in repository:", dir)
- p := l.projects.At(dir)
+ p, err := l.projects.At(dir)
+ if err != nil {
+ return err
+ }
if p == nil {
return errors.New("project is not found. check current project is initialized as Git repository and \".github/workflows\" directory exists")
}
@@ -240,14 +243,17 @@ func (l *Linter) GenerateDefaultConfig(dir string) error {
func (l *Linter) LintRepository(dir string) ([]*Error, error) {
l.log("Linting all workflow files in repository:", dir)
- proj := l.projects.At(dir)
- if proj == nil {
+ p, err := l.projects.At(dir)
+ if err != nil {
+ return nil, err
+ }
+ if p == nil {
return nil, fmt.Errorf("no project was found in any parent directories of %q. check workflows directory is put correctly in your Git repository", dir)
}
- l.log("Detected project:", proj.RootDir())
- wd := proj.WorkflowsDir()
- return l.LintDir(wd, proj)
+ l.log("Detected project:", p.RootDir())
+ wd := p.WorkflowsDir()
+ return l.LintDir(wd, p)
}
// LintDir lints all YAML workflow files in the given directory recursively.
@@ -316,14 +322,18 @@ func (l *Linter) LintFiles(filepaths []string, project *Project) ([]*Error, erro
for i := range ws {
// Each element of ws is accessed by single goroutine so mutex is unnecessary
w := &ws[i]
- p := project
- if p == nil {
+ proj := project
+ if proj == nil {
// This method modifies state of l.projects so it cannot be called in parallel.
// Before entering goroutine, resolve project instance.
- p = l.projects.At(w.path)
+ p, err := l.projects.At(w.path)
+ if err != nil {
+ return nil, err
+ }
+ proj = p
}
- ac := acf.GetCache(p) // #173
- rwc := rwcf.GetCache(p)
+ ac := acf.GetCache(proj) // #173
+ rwc := rwcf.GetCache(proj)
eg.Go(func() error {
// Bound concurrency on reading files to avoid "too many files to open" error (issue #3)
@@ -339,7 +349,7 @@ func (l *Linter) LintFiles(filepaths []string, project *Project) ([]*Error, erro
w.path = r // Use relative path if possible
}
}
- errs, err := l.check(w.path, src, p, proc, ac, rwc)
+ errs, err := l.check(w.path, src, proj, proc, ac, rwc)
if err != nil {
return fmt.Errorf("fatal error while checking %s: %w", w.path, err)
}
@@ -389,7 +399,11 @@ func (l *Linter) LintFiles(filepaths []string, project *Project) ([]*Error, erro
// parameter can be nil. In the case, the project is detected from the given path.
func (l *Linter) LintFile(path string, project *Project) ([]*Error, error) {
if project == nil {
- project = l.projects.At(path)
+ p, err := l.projects.At(path)
+ if err != nil {
+ return nil, err
+ }
+ project = p
}
src, err := os.ReadFile(path)
@@ -428,7 +442,11 @@ func (l *Linter) LintFile(path string, project *Project) ([]*Error, error) {
func (l *Linter) Lint(path string, content []byte, project *Project) ([]*Error, error) {
if project == nil && path != "" {
if _, err := os.Stat(path); !errors.Is(err, fs.ErrNotExist) {
- project = l.projects.At(path)
+ p, err := l.projects.At(path)
+ if err != nil {
+ return nil, err
+ }
+ project = p
}
}
proc := newConcurrentProcess(runtime.NumCPU())
@@ -471,13 +489,10 @@ func (l *Linter) check(
var cfg *Config
if l.defaultConfig != nil {
+ // `-config-file` option has higher prioritiy than repository config file
cfg = l.defaultConfig
} else if project != nil {
- c, err := project.LoadConfig()
- if err != nil {
- return nil, err
- }
- cfg = c
+ cfg = project.Config()
}
if cfg != nil {
l.debug("Config: %#v", cfg)
diff --git a/linter_test.go b/linter_test.go
index a91addcc5..ac990053f 100644
--- a/linter_test.go
+++ b/linter_test.go
@@ -289,10 +289,6 @@ func TestLinterFormatErrorMessageOK(t *testing.T) {
file: "test.jsonl",
format: "{{range $err := .}}{{json $err}}{{end}}",
},
- {
- file: "test.jsonl",
- format: "{{range $err := .}}{{json $err}}{{end}}",
- },
{
file: "test.md",
format: "{{range $ := .}}### Error at line {{$.Line}}, col {{$.Column}} of `{{$.Filepath}}`\\n\\n{{$.Message}}\\n\\n```\\n{{$.Snippet}}\\n```\\n\\n{{end}}",
diff --git a/popular_actions.go b/popular_actions.go
index 9b9f31e8e..333efd297 100644
--- a/popular_actions.go
+++ b/popular_actions.go
@@ -77,7 +77,8 @@ var PopularActions = map[string]*ActionMetadata{
"slot-name": {"slot-name", false},
},
Outputs: ActionMetadataOutputs{
- "app-url": {"app-url"},
+ "app-url": {"app-url"},
+ "package-url": {"package-url"},
},
},
"EnricoMi/publish-unit-test-result-action@v1": {
@@ -117,42 +118,44 @@ var PopularActions = map[string]*ActionMetadata{
"EnricoMi/publish-unit-test-result-action@v2": {
Name: "Publish Test Results",
Inputs: ActionMetadataInputs{
- "action_fail": {"action_fail", false},
- "action_fail_on_inconclusive": {"action_fail_on_inconclusive", false},
- "check_name": {"check_name", false},
- "check_run_annotations": {"check_run_annotations", false},
- "check_run_annotations_branch": {"check_run_annotations_branch", false},
- "comment_mode": {"comment_mode", false},
- "comment_title": {"comment_title", false},
- "commit": {"commit", false},
- "compare_to_earlier_commit": {"compare_to_earlier_commit", false},
- "deduplicate_classes_by_file_name": {"deduplicate_classes_by_file_name", false},
- "event_file": {"event_file", false},
- "event_name": {"event_name", false},
- "fail_on": {"fail_on", false},
- "files": {"files", false},
- "github_retries": {"github_retries", false},
- "github_token": {"github_token", false},
- "github_token_actor": {"github_token_actor", false},
- "ignore_runs": {"ignore_runs", false},
- "job_summary": {"job_summary", false},
- "json_file": {"json_file", false},
- "json_suite_details": {"json_suite_details", false},
- "json_test_case_results": {"json_test_case_results", false},
- "json_thousands_separator": {"json_thousands_separator", false},
- "junit_files": {"junit_files", false},
- "large_files": {"large_files", false},
- "nunit_files": {"nunit_files", false},
- "pull_request_build": {"pull_request_build", false},
- "report_individual_runs": {"report_individual_runs", false},
- "report_suite_logs": {"report_suite_logs", false},
- "search_pull_requests": {"search_pull_requests", false},
- "seconds_between_github_reads": {"seconds_between_github_reads", false},
- "seconds_between_github_writes": {"seconds_between_github_writes", false},
- "test_changes_limit": {"test_changes_limit", false},
- "time_unit": {"time_unit", false},
- "trx_files": {"trx_files", false},
- "xunit_files": {"xunit_files", false},
+ "action_fail": {"action_fail", false},
+ "action_fail_on_inconclusive": {"action_fail_on_inconclusive", false},
+ "check_name": {"check_name", false},
+ "check_run_annotations": {"check_run_annotations", false},
+ "check_run_annotations_branch": {"check_run_annotations_branch", false},
+ "comment_mode": {"comment_mode", false},
+ "comment_title": {"comment_title", false},
+ "commit": {"commit", false},
+ "compare_to_earlier_commit": {"compare_to_earlier_commit", false},
+ "deduplicate_classes_by_file_name": {"deduplicate_classes_by_file_name", false},
+ "event_file": {"event_file", false},
+ "event_name": {"event_name", false},
+ "fail_on": {"fail_on", false},
+ "files": {"files", false},
+ "github_retries": {"github_retries", false},
+ "github_token": {"github_token", false},
+ "github_token_actor": {"github_token_actor", false},
+ "ignore_runs": {"ignore_runs", false},
+ "job_summary": {"job_summary", false},
+ "json_file": {"json_file", false},
+ "json_suite_details": {"json_suite_details", false},
+ "json_test_case_results": {"json_test_case_results", false},
+ "json_thousands_separator": {"json_thousands_separator", false},
+ "junit_files": {"junit_files", false},
+ "large_files": {"large_files", false},
+ "nunit_files": {"nunit_files", false},
+ "pull_request_build": {"pull_request_build", false},
+ "report_individual_runs": {"report_individual_runs", false},
+ "report_suite_logs": {"report_suite_logs", false},
+ "search_pull_requests": {"search_pull_requests", false},
+ "secondary_rate_limit_wait_seconds": {"secondary_rate_limit_wait_seconds", false},
+ "seconds_between_github_reads": {"seconds_between_github_reads", false},
+ "seconds_between_github_writes": {"seconds_between_github_writes", false},
+ "test_changes_limit": {"test_changes_limit", false},
+ "test_file_prefix": {"test_file_prefix", false},
+ "time_unit": {"time_unit", false},
+ "trx_files": {"trx_files", false},
+ "xunit_files": {"xunit_files", false},
},
Outputs: ActionMetadataOutputs{
"json": {"json"},
@@ -268,6 +271,7 @@ var PopularActions = map[string]*ActionMetadata{
"cache-all-crates": {"cache-all-crates", false},
"cache-directories": {"cache-directories", false},
"cache-on-failure": {"cache-on-failure", false},
+ "cache-provider": {"cache-provider", false},
"cache-targets": {"cache-targets", false},
"env-vars": {"env-vars", false},
"key": {"key", false},
@@ -533,6 +537,30 @@ var PopularActions = map[string]*ActionMetadata{
Inputs: ActionMetadataInputs{
"clean": {"clean", false},
"fetch-depth": {"fetch-depth", false},
+ "fetch-tags": {"fetch-tags", false},
+ "github-server-url": {"github-server-url", false},
+ "lfs": {"lfs", false},
+ "path": {"path", false},
+ "persist-credentials": {"persist-credentials", false},
+ "ref": {"ref", false},
+ "repository": {"repository", false},
+ "set-safe-directory": {"set-safe-directory", false},
+ "sparse-checkout": {"sparse-checkout", false},
+ "sparse-checkout-cone-mode": {"sparse-checkout-cone-mode", false},
+ "ssh-key": {"ssh-key", false},
+ "ssh-known-hosts": {"ssh-known-hosts", false},
+ "ssh-strict": {"ssh-strict", false},
+ "submodules": {"submodules", false},
+ "token": {"token", false},
+ },
+ },
+ "actions/checkout@v4": {
+ Name: "Checkout",
+ Inputs: ActionMetadataInputs{
+ "clean": {"clean", false},
+ "fetch-depth": {"fetch-depth", false},
+ "fetch-tags": {"fetch-tags", false},
+ "filter": {"filter", false},
"github-server-url": {"github-server-url", false},
"lfs": {"lfs", false},
"path": {"path", false},
@@ -540,6 +568,7 @@ var PopularActions = map[string]*ActionMetadata{
"ref": {"ref", false},
"repository": {"repository", false},
"set-safe-directory": {"set-safe-directory", false},
+ "show-progress": {"show-progress", false},
"sparse-checkout": {"sparse-checkout", false},
"sparse-checkout-cone-mode": {"sparse-checkout-cone-mode", false},
"ssh-key": {"ssh-key", false},
@@ -651,20 +680,24 @@ var PopularActions = map[string]*ActionMetadata{
"actions/dependency-review-action@v3": {
Name: "Dependency Review",
Inputs: ActionMetadataInputs{
- "allow-dependencies-licenses": {"allow-dependencies-licenses", false},
- "allow-ghsas": {"allow-ghsas", false},
- "allow-licenses": {"allow-licenses", false},
- "base-ref": {"base-ref", false},
- "comment-summary-in-pr": {"comment-summary-in-pr", false},
- "config-file": {"config-file", false},
- "deny-licenses": {"deny-licenses", false},
- "external-repo-token": {"external-repo-token", false},
- "fail-on-scopes": {"fail-on-scopes", false},
- "fail-on-severity": {"fail-on-severity", false},
- "head-ref": {"head-ref", false},
- "license-check": {"license-check", false},
- "repo-token": {"repo-token", false},
- "vulnerability-check": {"vulnerability-check", false},
+ "allow-dependencies-licenses": {"allow-dependencies-licenses", false},
+ "allow-ghsas": {"allow-ghsas", false},
+ "allow-licenses": {"allow-licenses", false},
+ "base-ref": {"base-ref", false},
+ "comment-summary-in-pr": {"comment-summary-in-pr", false},
+ "config-file": {"config-file", false},
+ "deny-groups": {"deny-groups", false},
+ "deny-licenses": {"deny-licenses", false},
+ "deny-packages": {"deny-packages", false},
+ "external-repo-token": {"external-repo-token", false},
+ "fail-on-scopes": {"fail-on-scopes", false},
+ "fail-on-severity": {"fail-on-severity", false},
+ "head-ref": {"head-ref", false},
+ "license-check": {"license-check", false},
+ "repo-token": {"repo-token", false},
+ "retry-on-snapshot-warnings": {"retry-on-snapshot-warnings", false},
+ "retry-on-snapshot-warnings-timeout": {"retry-on-snapshot-warnings-timeout", false},
+ "vulnerability-check": {"vulnerability-check", false},
},
},
"actions/deploy-pages@v1": {
@@ -1578,6 +1611,70 @@ var PopularActions = map[string]*ActionMetadata{
"aws-account-id": {"aws-account-id"},
},
},
+ "aws-actions/configure-aws-credentials@v3": {
+ Name: "\"Configure AWS Credentials\" Action for GitHub Actions",
+ Inputs: ActionMetadataInputs{
+ "audience": {"audience", false},
+ "aws-access-key-id": {"aws-access-key-id", false},
+ "aws-region": {"aws-region", true},
+ "aws-secret-access-key": {"aws-secret-access-key", false},
+ "aws-session-token": {"aws-session-token", false},
+ "disable-retry": {"disable-retry", false},
+ "http-proxy": {"http-proxy", false},
+ "inline-session-policy": {"inline-session-policy", false},
+ "managed-session-policies": {"managed-session-policies", false},
+ "mask-aws-account-id": {"mask-aws-account-id", false},
+ "output-credentials": {"output-credentials", false},
+ "retry-max-attempts": {"retry-max-attempts", false},
+ "role-chaining": {"role-chaining", false},
+ "role-duration-seconds": {"role-duration-seconds", false},
+ "role-external-id": {"role-external-id", false},
+ "role-session-name": {"role-session-name", false},
+ "role-skip-session-tagging": {"role-skip-session-tagging", false},
+ "role-to-assume": {"role-to-assume", false},
+ "special-characters-workaround": {"special-characters-workaround", false},
+ "unset-current-credentials": {"unset-current-credentials", false},
+ "web-identity-token-file": {"web-identity-token-file", false},
+ },
+ Outputs: ActionMetadataOutputs{
+ "aws-access-key-id": {"aws-access-key-id"},
+ "aws-account-id": {"aws-account-id"},
+ "aws-secret-access-key": {"aws-secret-access-key"},
+ "aws-session-token": {"aws-session-token"},
+ },
+ },
+ "aws-actions/configure-aws-credentials@v4": {
+ Name: "\"Configure AWS Credentials\" Action for GitHub Actions",
+ Inputs: ActionMetadataInputs{
+ "audience": {"audience", false},
+ "aws-access-key-id": {"aws-access-key-id", false},
+ "aws-region": {"aws-region", true},
+ "aws-secret-access-key": {"aws-secret-access-key", false},
+ "aws-session-token": {"aws-session-token", false},
+ "disable-retry": {"disable-retry", false},
+ "http-proxy": {"http-proxy", false},
+ "inline-session-policy": {"inline-session-policy", false},
+ "managed-session-policies": {"managed-session-policies", false},
+ "mask-aws-account-id": {"mask-aws-account-id", false},
+ "output-credentials": {"output-credentials", false},
+ "retry-max-attempts": {"retry-max-attempts", false},
+ "role-chaining": {"role-chaining", false},
+ "role-duration-seconds": {"role-duration-seconds", false},
+ "role-external-id": {"role-external-id", false},
+ "role-session-name": {"role-session-name", false},
+ "role-skip-session-tagging": {"role-skip-session-tagging", false},
+ "role-to-assume": {"role-to-assume", false},
+ "special-characters-workaround": {"special-characters-workaround", false},
+ "unset-current-credentials": {"unset-current-credentials", false},
+ "web-identity-token-file": {"web-identity-token-file", false},
+ },
+ Outputs: ActionMetadataOutputs{
+ "aws-access-key-id": {"aws-access-key-id"},
+ "aws-account-id": {"aws-account-id"},
+ "aws-secret-access-key": {"aws-secret-access-key"},
+ "aws-session-token": {"aws-session-token"},
+ },
+ },
"azure/aks-set-context@v1": {
Name: "Azure Kubernetes set context",
Inputs: ActionMetadataInputs{
@@ -1819,7 +1916,7 @@ var PopularActions = map[string]*ActionMetadata{
"server_address": {"server_address", false},
"server_port": {"server_port", false},
"subject": {"subject", true},
- "to": {"to", true},
+ "to": {"to", false},
"username": {"username", false},
},
},
@@ -2063,6 +2160,46 @@ var PopularActions = map[string]*ActionMetadata{
"metadata": {"metadata"},
},
},
+ "docker/build-push-action@v5": {
+ Name: "Build and push Docker images",
+ Inputs: ActionMetadataInputs{
+ "add-hosts": {"add-hosts", false},
+ "allow": {"allow", false},
+ "attests": {"attests", false},
+ "build-args": {"build-args", false},
+ "build-contexts": {"build-contexts", false},
+ "builder": {"builder", false},
+ "cache-from": {"cache-from", false},
+ "cache-to": {"cache-to", false},
+ "cgroup-parent": {"cgroup-parent", false},
+ "context": {"context", false},
+ "file": {"file", false},
+ "github-token": {"github-token", false},
+ "labels": {"labels", false},
+ "load": {"load", false},
+ "network": {"network", false},
+ "no-cache": {"no-cache", false},
+ "no-cache-filters": {"no-cache-filters", false},
+ "outputs": {"outputs", false},
+ "platforms": {"platforms", false},
+ "provenance": {"provenance", false},
+ "pull": {"pull", false},
+ "push": {"push", false},
+ "sbom": {"sbom", false},
+ "secret-files": {"secret-files", false},
+ "secrets": {"secrets", false},
+ "shm-size": {"shm-size", false},
+ "ssh": {"ssh", false},
+ "tags": {"tags", false},
+ "target": {"target", false},
+ "ulimit": {"ulimit", false},
+ },
+ Outputs: ActionMetadataOutputs{
+ "digest": {"digest"},
+ "imageid": {"imageid"},
+ "metadata": {"metadata"},
+ },
+ },
"docker/login-action@v1": {
Name: "Docker Login",
Inputs: ActionMetadataInputs{
@@ -2083,6 +2220,16 @@ var PopularActions = map[string]*ActionMetadata{
"username": {"username", false},
},
},
+ "docker/login-action@v3": {
+ Name: "Docker Login",
+ Inputs: ActionMetadataInputs{
+ "ecr": {"ecr", false},
+ "logout": {"logout", false},
+ "password": {"password", false},
+ "registry": {"registry", false},
+ "username": {"username", false},
+ },
+ },
"docker/metadata-action@v1": {
Name: "Docker Meta",
Inputs: ActionMetadataInputs{
@@ -2170,6 +2317,27 @@ var PopularActions = map[string]*ActionMetadata{
"version": {"version"},
},
},
+ "docker/metadata-action@v5": {
+ Name: "Docker Metadata action",
+ Inputs: ActionMetadataInputs{
+ "bake-target": {"bake-target", false},
+ "context": {"context", false},
+ "flavor": {"flavor", false},
+ "github-token": {"github-token", false},
+ "images": {"images", true},
+ "labels": {"labels", false},
+ "sep-labels": {"sep-labels", false},
+ "sep-tags": {"sep-tags", false},
+ "tags": {"tags", false},
+ },
+ Outputs: ActionMetadataOutputs{
+ "bake-file": {"bake-file"},
+ "json": {"json"},
+ "labels": {"labels"},
+ "tags": {"tags"},
+ "version": {"version"},
+ },
+ },
"docker/setup-buildx-action@v1": {
Name: "Docker Setup Buildx",
Inputs: ActionMetadataInputs{
@@ -2218,6 +2386,32 @@ var PopularActions = map[string]*ActionMetadata{
"status": {"status"},
},
},
+ "docker/setup-buildx-action@v3": {
+ Name: "Docker Setup Buildx",
+ Inputs: ActionMetadataInputs{
+ "append": {"append", false},
+ "buildkitd-flags": {"buildkitd-flags", false},
+ "cleanup": {"cleanup", false},
+ "config": {"config", false},
+ "config-inline": {"config-inline", false},
+ "driver": {"driver", false},
+ "driver-opts": {"driver-opts", false},
+ "endpoint": {"endpoint", false},
+ "install": {"install", false},
+ "platforms": {"platforms", false},
+ "use": {"use", false},
+ "version": {"version", false},
+ },
+ Outputs: ActionMetadataOutputs{
+ "driver": {"driver"},
+ "endpoint": {"endpoint"},
+ "flags": {"flags"},
+ "name": {"name"},
+ "nodes": {"nodes"},
+ "platforms": {"platforms"},
+ "status": {"status"},
+ },
+ },
"docker/setup-qemu-action@v1": {
Name: "Docker Setup QEMU",
Inputs: ActionMetadataInputs{
@@ -2238,6 +2432,16 @@ var PopularActions = map[string]*ActionMetadata{
"platforms": {"platforms"},
},
},
+ "docker/setup-qemu-action@v3": {
+ Name: "Docker Setup QEMU",
+ Inputs: ActionMetadataInputs{
+ "image": {"image", false},
+ "platforms": {"platforms", false},
+ },
+ Outputs: ActionMetadataOutputs{
+ "platforms": {"platforms"},
+ },
+ },
"dorny/paths-filter@v1": {
Name: "Pull request changed files filter",
Inputs: ActionMetadataInputs{
@@ -2384,6 +2588,63 @@ var PopularActions = map[string]*ActionMetadata{
"volume": {"volume"},
},
},
+ "game-ci/unity-builder@v3": {
+ Name: "Unity - Builder",
+ Inputs: ActionMetadataInputs{
+ "allowdirtybuild": {"allowDirtyBuild", false},
+ "androidexporttype": {"androidExportType", false},
+ "androidkeyaliasname": {"androidKeyaliasName", false},
+ "androidkeyaliaspass": {"androidKeyaliasPass", false},
+ "androidkeystorebase64": {"androidKeystoreBase64", false},
+ "androidkeystorename": {"androidKeystoreName", false},
+ "androidkeystorepass": {"androidKeystorePass", false},
+ "androidsymboltype": {"androidSymbolType", false},
+ "androidtargetsdkversion": {"androidTargetSdkVersion", false},
+ "androidversioncode": {"androidVersionCode", false},
+ "awsstackname": {"awsStackName", false},
+ "buildmethod": {"buildMethod", false},
+ "buildname": {"buildName", false},
+ "buildspath": {"buildsPath", false},
+ "cachekey": {"cacheKey", false},
+ "cacheunityinstallationonmac": {"cacheUnityInstallationOnMac", false},
+ "chownfilesto": {"chownFilesTo", false},
+ "cloudrunnercpu": {"cloudRunnerCpu", false},
+ "cloudrunnermemory": {"cloudRunnerMemory", false},
+ "containerhookfiles": {"containerHookFiles", false},
+ "customcommandhooks": {"customCommandHooks", false},
+ "customhookfiles": {"customHookFiles", false},
+ "customimage": {"customImage", false},
+ "customjob": {"customJob", false},
+ "customparameters": {"customParameters", false},
+ "dockerworkspacepath": {"dockerWorkspacePath", false},
+ "githubowner": {"githubOwner", false},
+ "gitprivatetoken": {"gitPrivateToken", false},
+ "kubeconfig": {"kubeConfig", false},
+ "kubestorageclass": {"kubeStorageClass", false},
+ "kubevolume": {"kubeVolume", false},
+ "kubevolumesize": {"kubeVolumeSize", false},
+ "postbuildsteps": {"postBuildSteps", false},
+ "prebuildsteps": {"preBuildSteps", false},
+ "projectpath": {"projectPath", false},
+ "providerstrategy": {"providerStrategy", false},
+ "readinputfromoverridelist": {"readInputFromOverrideList", false},
+ "readinputoverridecommand": {"readInputOverrideCommand", false},
+ "sshagent": {"sshAgent", false},
+ "sshpublickeysdirectorypath": {"sshPublicKeysDirectoryPath", false},
+ "targetplatform": {"targetPlatform", false},
+ "unityhubversiononmac": {"unityHubVersionOnMac", false},
+ "unitylicensingserver": {"unityLicensingServer", false},
+ "unityversion": {"unityVersion", false},
+ "version": {"version", false},
+ "versioning": {"versioning", false},
+ "watchtoend": {"watchToEnd", false},
+ },
+ Outputs: ActionMetadataOutputs{
+ "androidversioncode": {"androidVersionCode"},
+ "buildversion": {"buildVersion"},
+ "volume": {"volume"},
+ },
+ },
"getsentry/paths-filter@v1": {
Name: "Pull request changed files filter",
Inputs: ActionMetadataInputs{
@@ -2668,6 +2929,20 @@ var PopularActions = map[string]*ActionMetadata{
"metadata": {"metadata"},
},
},
+ "goreleaser/goreleaser-action@v5": {
+ Name: "GoReleaser Action",
+ Inputs: ActionMetadataInputs{
+ "args": {"args", false},
+ "distribution": {"distribution", false},
+ "install-only": {"install-only", false},
+ "version": {"version", false},
+ "workdir": {"workdir", false},
+ },
+ Outputs: ActionMetadataOutputs{
+ "artifacts": {"artifacts"},
+ "metadata": {"metadata"},
+ },
+ },
"gradle/wrapper-validation-action@v1": {
Name: "Gradle Wrapper Validation",
Inputs: ActionMetadataInputs{
@@ -2961,6 +3236,7 @@ var PopularActions = map[string]*ActionMetadata{
"deploy-message": {"deploy-message", false},
"enable-commit-comment": {"enable-commit-comment", false},
"enable-commit-status": {"enable-commit-status", false},
+ "enable-github-deployment": {"enable-github-deployment", false},
"enable-pull-request-comment": {"enable-pull-request-comment", false},
"fails-without-credentials": {"fails-without-credentials", false},
"functions-dir": {"functions-dir", false},
diff --git a/project.go b/project.go
index 2aebca110..7a35392b7 100644
--- a/project.go
+++ b/project.go
@@ -21,25 +21,33 @@ func absPath(path string) string {
// findProject creates new Project instance by finding a project which the given path belongs to.
// A project must be a Git repository and have ".github/workflows" directory.
-func findProject(path string) *Project {
+func findProject(path string) (*Project, error) {
d := absPath(path)
for {
- w := filepath.Join(d, ".github", "workflows")
- if s, err := os.Stat(w); err == nil && s.IsDir() {
- g := filepath.Join(d, ".git")
- if _, err := os.Stat(g); err == nil { // Note: .git may be a file
- return &Project{root: d}
+ if s, err := os.Stat(filepath.Join(d, ".github", "workflows")); err == nil && s.IsDir() {
+ if _, err := os.Stat(filepath.Join(d, ".git")); err == nil { // Note: .git may be a file
+ return NewProject(d)
}
}
p := filepath.Dir(d)
if p == d {
- return nil
+ return nil, nil
}
d = p
}
}
+// NewProject creates a new instance with a file path to the root directory of the repository.
+// This function returns an error when failing to parse an actionlint config file in the repository.
+func NewProject(root string) (*Project, error) {
+ c, err := loadRepoConfig(root)
+ if err != nil {
+ return nil, err
+ }
+ return &Project{root, c}, nil
+}
+
// RootDir returns a root directory path of the GitHub project repository.
func (p *Project) RootDir() string {
return p.root
@@ -58,28 +66,12 @@ func (p *Project) Knows(path string) bool {
return strings.HasPrefix(absPath(path), p.root)
}
-// LoadConfig returns config object of the GitHub project repository. The config file is read from
-// ".github/actionlint.yaml" or ".github/actionlint.yml".
-func (p *Project) LoadConfig() (*Config, error) {
- if p.config != nil {
- return p.config, nil
- }
-
- for _, f := range []string{"actionlint.yaml", "actionlint.yml"} {
- path := filepath.Join(p.root, ".github", f)
- b, err := os.ReadFile(path)
- if err != nil {
- continue // file does not exist
- }
- cfg, err := parseConfig(b, path)
- if err != nil {
- return nil, err
- }
- p.config = cfg
- return cfg, nil
- }
-
- return nil, nil // not found
+// Config returns config object of the GitHub project repository. The config file was read from
+// ".github/actionlint.yaml" or ".github/actionlint.yml" when this Project instance was created.
+// When no config was found, this method returns nil.
+func (p *Project) Config() *Config {
+ // Note: Calling this method must be thread safe (#333)
+ return p.config
}
// Projects represents set of projects. It caches Project instances which was created previously
@@ -95,17 +87,20 @@ func NewProjects() *Projects {
// At returns the Project instance which the path belongs to. It returns nil if no project is found
// from the path.
-func (ps *Projects) At(path string) *Project {
+func (ps *Projects) At(path string) (*Project, error) {
for _, p := range ps.known {
if p.Knows(path) {
- return p
+ return p, nil
}
}
- p := findProject(path)
+ p, err := findProject(path)
+ if err != nil {
+ return nil, err
+ }
if p != nil {
ps.known = append(ps.known, p)
}
- return p
+ return p, nil
}
diff --git a/project_test.go b/project_test.go
index 394130b45..e3b4d2676 100644
--- a/project_test.go
+++ b/project_test.go
@@ -3,6 +3,7 @@ package actionlint
import (
"os"
"path/filepath"
+ "strings"
"testing"
)
@@ -57,7 +58,10 @@ func TestProjectsFindProjectFromPath(t *testing.T) {
},
} {
t.Run(tc.what, func(t *testing.T) {
- p := ps.At(tc.path)
+ p, err := ps.At(tc.path)
+ if err != nil {
+ t.Fatal(err)
+ }
r := p.RootDir()
if r != abs {
@@ -65,7 +69,10 @@ func TestProjectsFindProjectFromPath(t *testing.T) {
}
// Result should be cached
- p2 := ps.At(tc.path)
+ p2, err := ps.At(tc.path)
+ if err != nil {
+ t.Fatal(err)
+ }
if p != p2 {
t.Fatalf("project %v is not cached. New project is %v. %p v.s. %p", p, p2, p, p2)
}
@@ -83,8 +90,60 @@ func TestProjectsDoesNotFindProjectFromOutside(t *testing.T) {
outside := filepath.Join(d, "..")
ps := NewProjects()
- p := ps.At(outside)
+ p, err := ps.At(outside)
+ if err != nil {
+ t.Fatal(err)
+ }
if p != nil && p.RootDir() == abs {
t.Fatalf("project %v is detected from outside of the project %q", p, outside)
}
}
+
+func TestProjectsLoadingProjectConfig(t *testing.T) {
+ d := filepath.Join("testdata", "config", "projects", "ok")
+ testEnsureDotGitDir(d)
+ ps := NewProjects()
+ p, err := ps.At(d)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if p == nil {
+ t.Fatal("project was not found at", d)
+ }
+ if c := p.Config(); c == nil {
+ t.Fatal("config was not found for directory", d)
+ }
+}
+
+func TestProjectsLoadingNoProjectConfig(t *testing.T) {
+ d := filepath.Join("testdata", "config", "projects", "none")
+ testEnsureDotGitDir(d)
+ ps := NewProjects()
+ p, err := ps.At(d)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if p == nil {
+ t.Fatal("project was not found at", d)
+ }
+ if c := p.Config(); c != nil {
+ t.Fatal("config was found for directory", d)
+ }
+}
+
+func TestProjectsLoadingBrokenProjectConfig(t *testing.T) {
+ want := "could not parse config file"
+ d := filepath.Join("testdata", "config", "projects", "err")
+ testEnsureDotGitDir(d)
+ ps := NewProjects()
+ p, err := ps.At(d)
+ if err == nil {
+ t.Fatalf("wanted error %q but have no error", want)
+ }
+ if p != nil {
+ t.Fatal("project was returned though getting config failed", p)
+ }
+ if msg := err.Error(); !strings.Contains(msg, want) {
+ t.Fatalf("wanted error %q but have error %q", want, msg)
+ }
+}
diff --git a/rule_runner_label.go b/rule_runner_label.go
index 5fe446c67..21936499f 100644
--- a/rule_runner_label.go
+++ b/rule_runner_label.go
@@ -8,14 +8,15 @@ type runnerOSCompat uint
const (
compatInvalid = 0
- compatUbuntu1804 runnerOSCompat = 1 << iota
- compatUbuntu2004
+ compatUbuntu2004 runnerOSCompat = 1 << iota
compatUbuntu2204
compatMacOS1015
compatMacOS110
compatMacOS120
+ compatMacOS120L
compatMacOS120XL
compatMacOS130
+ compatMacOS130L
compatMacOS130XL
compatWindows2016
compatWindows2019
@@ -31,13 +32,18 @@ var allGitHubHostedRunnerLabels = []string{
"ubuntu-latest",
"ubuntu-22.04",
"ubuntu-20.04",
- "ubuntu-18.04",
"macos-latest",
"macos-latest-xl",
+ "macos-latest-xlarge",
+ "macos-latest-large",
"macos-13-xl",
+ "macos-13-xlarge",
+ "macos-13-large",
"macos-13",
"macos-13.0",
"macos-12-xl",
+ "macos-12-xlarge",
+ "macos-12-large",
"macos-12",
"macos-12.0",
"macos-11",
@@ -61,28 +67,33 @@ var selfHostedRunnerPresetOtherLabels = []string{
}
var defaultRunnerOSCompats = map[string]runnerOSCompat{
- "ubuntu-latest": compatUbuntu2204,
- "ubuntu-22.04": compatUbuntu2204,
- "ubuntu-20.04": compatUbuntu2004,
- "ubuntu-18.04": compatUbuntu1804,
- "macos-13-xl": compatMacOS130XL,
- "macos-13": compatMacOS130,
- "macos-13.0": compatMacOS130,
- "macos-latest-xl": compatMacOS120XL,
- "macos-latest": compatMacOS120,
- "macos-12-xl": compatMacOS120XL,
- "macos-12": compatMacOS120,
- "macos-12.0": compatMacOS120,
- "macos-11": compatMacOS110,
- "macos-11.0": compatMacOS110,
- "macos-10.15": compatMacOS1015,
- "windows-latest": compatWindows2022,
- "windows-2022": compatWindows2022,
- "windows-2019": compatWindows2019,
- "windows-2016": compatWindows2016,
- "linux": compatUbuntu2204 | compatUbuntu2004 | compatUbuntu1804, // Note: "linux" does not always indicate Ubuntu. It might be Fedora or Arch or ...
- "macos": compatMacOS130 | compatMacOS130XL | compatMacOS120 | compatMacOS120XL | compatMacOS110 | compatMacOS1015,
- "windows": compatWindows2022 | compatWindows2019 | compatWindows2016,
+ "ubuntu-latest": compatUbuntu2204,
+ "ubuntu-22.04": compatUbuntu2204,
+ "ubuntu-20.04": compatUbuntu2004,
+ "macos-13-xl": compatMacOS130XL,
+ "macos-13-xlarge": compatMacOS130XL,
+ "macos-13-large": compatMacOS130L,
+ "macos-13": compatMacOS130,
+ "macos-13.0": compatMacOS130,
+ "macos-latest-xl": compatMacOS120XL,
+ "macos-latest-xlarge": compatMacOS120XL,
+ "macos-latest-large": compatMacOS120L,
+ "macos-latest": compatMacOS120,
+ "macos-12-xl": compatMacOS120XL,
+ "macos-12-xlarge": compatMacOS120XL,
+ "macos-12-large": compatMacOS120L,
+ "macos-12": compatMacOS120,
+ "macos-12.0": compatMacOS120,
+ "macos-11": compatMacOS110,
+ "macos-11.0": compatMacOS110,
+ "macos-10.15": compatMacOS1015,
+ "windows-latest": compatWindows2022,
+ "windows-2022": compatWindows2022,
+ "windows-2019": compatWindows2019,
+ "windows-2016": compatWindows2016,
+ "linux": compatUbuntu2204 | compatUbuntu2004, // Note: "linux" does not always indicate Ubuntu. It might be Fedora or Arch or ...
+ "macos": compatMacOS130 | compatMacOS130L | compatMacOS130XL | compatMacOS120 | compatMacOS120L | compatMacOS120XL | compatMacOS110 | compatMacOS1015,
+ "windows": compatWindows2022 | compatWindows2019 | compatWindows2016,
}
// RuleRunnerLabel is a rule to check runner label like "ubuntu-latest". There are two types of
diff --git a/scripts/download-actionlint.bash b/scripts/download-actionlint.bash
index e1e8e293e..00c401a6f 100755
--- a/scripts/download-actionlint.bash
+++ b/scripts/download-actionlint.bash
@@ -43,7 +43,7 @@ if [[ "$1" == "-h" || "$1" == "--help" ]]; then
fi
# Default value is updated manually on release
-version="1.6.25"
+version="1.6.26"
if [ -n "$1" ]; then
if [[ "$1" != 'latest' && "$1" != 'LATEST' ]]; then
if [[ "$1" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
diff --git a/scripts/generate-popular-actions/main.go b/scripts/generate-popular-actions/main.go
index 39b11f2f9..e7b27e18b 100644
--- a/scripts/generate-popular-actions/main.go
+++ b/scripts/generate-popular-actions/main.go
@@ -136,8 +136,8 @@ var popularActions = []*action{
},
{
slug: "actions/checkout",
- tags: []string{"v1", "v2", "v3"},
- next: "v4",
+ tags: []string{"v1", "v2", "v3", "v4"},
+ next: "v5",
},
{
slug: "actions/configure-pages",
@@ -220,8 +220,8 @@ var popularActions = []*action{
},
{
slug: "aws-actions/configure-aws-credentials",
- tags: []string{"v1", "v2"},
- next: "v3",
+ tags: []string{"v1", "v2", "v3", "v4"},
+ next: "v5",
},
{
slug: "azure/aks-set-context",
@@ -259,28 +259,28 @@ var popularActions = []*action{
next: "v5"}, // v1 does not exist
{
slug: "docker/build-push-action",
- tags: []string{"v1", "v2", "v3", "v4"},
- next: "v5",
+ tags: []string{"v1", "v2", "v3", "v4", "v5"},
+ next: "v6",
},
{
slug: "docker/login-action",
- tags: []string{"v1", "v2"},
- next: "v3",
+ tags: []string{"v1", "v2", "v3"},
+ next: "v4",
},
{
slug: "docker/metadata-action",
- tags: []string{"v1", "v2", "v3", "v4"},
- next: "v5",
+ tags: []string{"v1", "v2", "v3", "v4", "v5"},
+ next: "v6",
},
{
slug: "docker/setup-buildx-action",
- tags: []string{"v1", "v2"},
- next: "v3",
+ tags: []string{"v1", "v2", "v3"},
+ next: "v4",
},
{
slug: "docker/setup-qemu-action",
- tags: []string{"v1", "v2"},
- next: "v3",
+ tags: []string{"v1", "v2", "v3"},
+ next: "v4",
},
{
slug: "dorny/paths-filter",
@@ -299,8 +299,8 @@ var popularActions = []*action{
},
{
slug: "game-ci/unity-builder",
- tags: []string{"v2"},
- next: "v3",
+ tags: []string{"v2", "v3"},
+ next: "v4",
},
{
slug: "getsentry/paths-filter",
@@ -342,8 +342,8 @@ var popularActions = []*action{
},
{
slug: "goreleaser/goreleaser-action",
- tags: []string{"v1", "v2", "v3", "v4"},
- next: "v5",
+ tags: []string{"v1", "v2", "v3", "v4", "v5"},
+ next: "v6",
},
{
slug: "gradle/wrapper-validation-action",
diff --git a/testdata/config/projects/err/.github/actionlint.yaml b/testdata/config/projects/err/.github/actionlint.yaml
new file mode 100644
index 000000000..ff5c75ed1
--- /dev/null
+++ b/testdata/config/projects/err/.github/actionlint.yaml
@@ -0,0 +1 @@
+self-hosted-runner: 42
diff --git a/testdata/config/projects/err/.github/workflows/test.yaml b/testdata/config/projects/err/.github/workflows/test.yaml
new file mode 100644
index 000000000..f1787617a
--- /dev/null
+++ b/testdata/config/projects/err/.github/workflows/test.yaml
@@ -0,0 +1,6 @@
+on: push
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ steps:
+ - run: echo
diff --git a/testdata/config/projects/none/.github/workflows/test.yaml b/testdata/config/projects/none/.github/workflows/test.yaml
new file mode 100644
index 000000000..f1787617a
--- /dev/null
+++ b/testdata/config/projects/none/.github/workflows/test.yaml
@@ -0,0 +1,6 @@
+on: push
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ steps:
+ - run: echo
diff --git a/testdata/config/projects/ok/.github/actionlint.yaml b/testdata/config/projects/ok/.github/actionlint.yaml
new file mode 100644
index 000000000..2617efc68
--- /dev/null
+++ b/testdata/config/projects/ok/.github/actionlint.yaml
@@ -0,0 +1,3 @@
+self-hosted-runner:
+ labels: []
+config-variables: null
diff --git a/testdata/config/projects/ok/.github/workflows/test.yaml b/testdata/config/projects/ok/.github/workflows/test.yaml
new file mode 100644
index 000000000..f1787617a
--- /dev/null
+++ b/testdata/config/projects/ok/.github/workflows/test.yaml
@@ -0,0 +1,6 @@
+on: push
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ steps:
+ - run: echo
diff --git a/testdata/format/README.md b/testdata/format/README.md
index fc819f960..1ad5d875a 100644
--- a/testdata/format/README.md
+++ b/testdata/format/README.md
@@ -14,3 +14,11 @@ sed -i 's/(devel)//' test.sarif
mv test.sarif testdata/format/
```
+
+How to generate other files:
+
+```sh
+./actionlint -pyflakes= -shellcheck= -format '{{json .}}' testdata/format/test.yaml > testdata/format/test.json
+./actionlint -pyflakes= -shellcheck= -format '{{range $err := .}}{{json $err}}{{end}}' testdata/format/test.yaml > testdata/format/test.jsonl
+./actionlint -pyflakes= -shellcheck= -format '{{range $ := .}}### Error at line {{$.Line}}, col {{$.Column}} of `{{$.Filepath}}`\n\n{{$.Message}}\n\n```\n{{$.Snippet}}\n```\n\n{{end}}' testdata/format/test.yaml > testdata/format/test.md
+```
diff --git a/testdata/format/test.json b/testdata/format/test.json
index c6d9949e3..8cd228ba6 100644
--- a/testdata/format/test.json
+++ b/testdata/format/test.json
@@ -1 +1 @@
-[{"message":"unexpected key \"branch\" for \"push\" section. expected one of \"branches\", \"branches-ignore\", \"paths\", \"paths-ignore\", \"tags\", \"tags-ignore\", \"types\", \"workflows\"","filepath":"testdata/format/test.yaml","line":3,"column":5,"kind":"syntax-check","snippet":" branch: main\n ^~~~~~~","end_column":11},{"message":"label \"linux-latest\" is unknown. available labels are \"windows-latest\", \"windows-2022\", \"windows-2019\", \"windows-2016\", \"ubuntu-latest\", \"ubuntu-22.04\", \"ubuntu-20.04\", \"ubuntu-18.04\", \"macos-latest\", \"macos-latest-xl\", \"macos-13-xl\", \"macos-13\", \"macos-13.0\", \"macos-12-xl\", \"macos-12\", \"macos-12.0\", \"macos-11\", \"macos-11.0\", \"macos-10.15\", \"self-hosted\", \"x64\", \"arm\", \"arm64\", \"linux\", \"macos\", \"windows\". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file","filepath":"testdata/format/test.yaml","line":6,"column":14,"kind":"runner-label","snippet":" runs-on: linux-latest\n ^~~~~~~~~~~~","end_column":25}]
+[{"message":"unexpected key \"branch\" for \"push\" section. expected one of \"branches\", \"branches-ignore\", \"paths\", \"paths-ignore\", \"tags\", \"tags-ignore\", \"types\", \"workflows\"","filepath":"testdata/format/test.yaml","line":3,"column":5,"kind":"syntax-check","snippet":" branch: main\n ^~~~~~~","end_column":11},{"message":"label \"linux-latest\" is unknown. available labels are \"windows-latest\", \"windows-2022\", \"windows-2019\", \"windows-2016\", \"ubuntu-latest\", \"ubuntu-22.04\", \"ubuntu-20.04\", \"macos-latest\", \"macos-latest-xl\", \"macos-latest-xlarge\", \"macos-latest-large\", \"macos-13-xl\", \"macos-13-xlarge\", \"macos-13-large\", \"macos-13\", \"macos-13.0\", \"macos-12-xl\", \"macos-12-xlarge\", \"macos-12-large\", \"macos-12\", \"macos-12.0\", \"macos-11\", \"macos-11.0\", \"macos-10.15\", \"self-hosted\", \"x64\", \"arm\", \"arm64\", \"linux\", \"macos\", \"windows\". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file","filepath":"testdata/format/test.yaml","line":6,"column":14,"kind":"runner-label","snippet":" runs-on: linux-latest\n ^~~~~~~~~~~~","end_column":25}]
diff --git a/testdata/format/test.jsonl b/testdata/format/test.jsonl
index c3ae89152..263e9a96f 100644
--- a/testdata/format/test.jsonl
+++ b/testdata/format/test.jsonl
@@ -1,2 +1,2 @@
{"message":"unexpected key \"branch\" for \"push\" section. expected one of \"branches\", \"branches-ignore\", \"paths\", \"paths-ignore\", \"tags\", \"tags-ignore\", \"types\", \"workflows\"","filepath":"testdata/format/test.yaml","line":3,"column":5,"kind":"syntax-check","snippet":" branch: main\n ^~~~~~~","end_column":11}
-{"message":"label \"linux-latest\" is unknown. available labels are \"windows-latest\", \"windows-2022\", \"windows-2019\", \"windows-2016\", \"ubuntu-latest\", \"ubuntu-22.04\", \"ubuntu-20.04\", \"ubuntu-18.04\", \"macos-latest\", \"macos-latest-xl\", \"macos-13-xl\", \"macos-13\", \"macos-13.0\", \"macos-12-xl\", \"macos-12\", \"macos-12.0\", \"macos-11\", \"macos-11.0\", \"macos-10.15\", \"self-hosted\", \"x64\", \"arm\", \"arm64\", \"linux\", \"macos\", \"windows\". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file","filepath":"testdata/format/test.yaml","line":6,"column":14,"kind":"runner-label","snippet":" runs-on: linux-latest\n ^~~~~~~~~~~~","end_column":25}
+{"message":"label \"linux-latest\" is unknown. available labels are \"windows-latest\", \"windows-2022\", \"windows-2019\", \"windows-2016\", \"ubuntu-latest\", \"ubuntu-22.04\", \"ubuntu-20.04\", \"macos-latest\", \"macos-latest-xl\", \"macos-latest-xlarge\", \"macos-latest-large\", \"macos-13-xl\", \"macos-13-xlarge\", \"macos-13-large\", \"macos-13\", \"macos-13.0\", \"macos-12-xl\", \"macos-12-xlarge\", \"macos-12-large\", \"macos-12\", \"macos-12.0\", \"macos-11\", \"macos-11.0\", \"macos-10.15\", \"self-hosted\", \"x64\", \"arm\", \"arm64\", \"linux\", \"macos\", \"windows\". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file","filepath":"testdata/format/test.yaml","line":6,"column":14,"kind":"runner-label","snippet":" runs-on: linux-latest\n ^~~~~~~~~~~~","end_column":25}
diff --git a/testdata/format/test.md b/testdata/format/test.md
index 71782da60..e1540020a 100644
--- a/testdata/format/test.md
+++ b/testdata/format/test.md
@@ -9,7 +9,7 @@ unexpected key "branch" for "push" section. expected one of "branches", "branche
### Error at line 6, col 14 of `testdata/format/test.yaml`
-label "linux-latest" is unknown. available labels are "windows-latest", "windows-2022", "windows-2019", "windows-2016", "ubuntu-latest", "ubuntu-22.04", "ubuntu-20.04", "ubuntu-18.04", "macos-latest", "macos-latest-xl", "macos-13-xl", "macos-13", "macos-13.0", "macos-12-xl", "macos-12", "macos-12.0", "macos-11", "macos-11.0", "macos-10.15", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file
+label "linux-latest" is unknown. available labels are "windows-latest", "windows-2022", "windows-2019", "windows-2016", "ubuntu-latest", "ubuntu-22.04", "ubuntu-20.04", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "macos-13.0", "macos-12-xl", "macos-12-xlarge", "macos-12-large", "macos-12", "macos-12.0", "macos-11", "macos-11.0", "macos-10.15", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file
```
runs-on: linux-latest
diff --git a/testdata/format/test.sarif b/testdata/format/test.sarif
index 0c26d06cc..cf105a87d 100644
--- a/testdata/format/test.sarif
+++ b/testdata/format/test.sarif
@@ -280,7 +280,7 @@
{
"ruleId": "runner-label",
"message": {
- "text": "label \"linux-latest\" is unknown. available labels are \"windows-latest\", \"windows-2022\", \"windows-2019\", \"windows-2016\", \"ubuntu-latest\", \"ubuntu-22.04\", \"ubuntu-20.04\", \"ubuntu-18.04\", \"macos-latest\", \"macos-latest-xl\", \"macos-13-xl\", \"macos-13\", \"macos-13.0\", \"macos-12-xl\", \"macos-12\", \"macos-12.0\", \"macos-11\", \"macos-11.0\", \"macos-10.15\", \"self-hosted\", \"x64\", \"arm\", \"arm64\", \"linux\", \"macos\", \"windows\". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file"
+ "text": "label \"linux-latest\" is unknown. available labels are \"windows-latest\", \"windows-2022\", \"windows-2019\", \"windows-2016\", \"ubuntu-latest\", \"ubuntu-22.04\", \"ubuntu-20.04\", \"macos-latest\", \"macos-latest-xl\", \"macos-latest-xlarge\", \"macos-latest-large\", \"macos-13-xl\", \"macos-13-xlarge\", \"macos-13-large\", \"macos-13\", \"macos-13.0\", \"macos-12-xl\", \"macos-12-xlarge\", \"macos-12-large\", \"macos-12\", \"macos-12.0\", \"macos-11\", \"macos-11.0\", \"macos-10.15\", \"self-hosted\", \"x64\", \"arm\", \"arm64\", \"linux\", \"macos\", \"windows\". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file"
},
"locations": [
{
diff --git a/testdata/projects/broken_local_action/workflows/test.yaml b/testdata/projects/broken_local_action/workflows/test.yaml
index a12e71ecb..0139f4ddc 100644
--- a/testdata/projects/broken_local_action/workflows/test.yaml
+++ b/testdata/projects/broken_local_action/workflows/test.yaml
@@ -2,7 +2,7 @@ on: push
jobs:
test:
- runs-on: ubuntu-18.04
+ runs-on: ubuntu-22.04
steps:
- uses: ./action/broken_input
with: