# Development

`make` (3.81 or later) is useful to run each tasks and reduce redundant builds/tests.

## How to build

```sh
go build ./cmd/actionlint
./actionlint -h
```

or

```sh
make build
```

It generates some sources with `go generate`.

## How to run tests

```sh
go test
```

or

```sh
make test
```

## How to run lint

[staticcheck](https://staticcheck.io/) is used to lint Go sources.

```sh
staticcheck ./ ./cmd/...
```

or

```sh
make lint
```

Note that `staticcheck ./...` is not available because it does not support `syscall/js` yet. `playground/main.go` hits
this issue.

## How to run fuzzer

Fuzz tests use [go-fuzz](https://github.com/dvyukov/go-fuzz). Install `go-fuzz` and `go-fuzz-build` in your system.

Since there are multiple fuzzing targets, `-func` argument is necessary. Specify a target which you want to run.

```sh
# Create first corpus
go-fuzz-build ./fuzz

# Run fuzzer
go-fuzz -bin ./actionlint_fuzz-fuzz.zip -func FuzzParse
```

or

```sh
make fuzz FUZZ_FUNC=FuzzParse
```

## How to release

When releasing v1.2.3 as example:

1. Ensure all changes were already pushed to remote by checking `git push origin master` outputs `Everything up-to-date`
2. Run `bash ./scripts/bump-version.bash 1.2.3`
3. Wait until [the CI release job](.github/workflows/release.yaml) completes successfully:
   - GoReleaser builds release binaries and make pre-release at GitHub and updates [Homebrew formula](./HomebrewFormula/actionlint.rb)
   - The CI job also updates version string in `./scripts/download-actionlint.bash`
4. Open the pre-release at [release page](https://github.com/rhysd/actionlint/releases) with browser
5. Write up release notes, uncheck pre-release checkbox and publish the new release
6. Run `changelog-from-release > CHANGELOG.md` locally to update [CHANGELOG.md](./CHANGELOG.md) and make a commit for the change
7. Run `git pull` to merge upstream changes to local `main` branch and run `git push origin main`
8. Update the playground by `./playground/deploy.bash` if it is not updated yet for the release

## How to generate the manual

`actionlint.1` manual is generated from [`actionlint.1.ronn`](./man/actionlint.1.ronn) by [ronn](https://github.com/rtomayko/ronn).

```sh
ronn ./man/actionlint.1.ronn
```

or

```sh
make ./man/actionlint.1
```

## How to develop playground

Visit [`playground/README.md`](./playground/README.md).

## How to deploy playground

Run [`deploy.bash`](./playground/deploy.bash) at root of repository. It does:

1. Ensures to install dependencies and to build `main.wasm`
2. Copy all assets to `./playground-dist` directory
3. Optimize `main.wasm` with `wasm-opt` which is a part of [Binaryen](https://github.com/WebAssembly/binaryen) toolchain
3. Switch branch to `gh-pages`
4. Move all files in `./playground-dist` to root of repository and add to repository
5. Make commit for deployment

```sh
# Prepare deployment
bash ./playground/deploy.bash
# Check it works fine by visiting localhost:1234
npm run serve
# If it looks good, deploy it
git push
```

## Maintain `popular_actions.go`

[`popular_actions.go`](./popular_actions.go) is generated automatically with `go generate`. The command runs
[`generate-popular-actions`](./scripts/generate-popular-actions) script.

The script also can detect new releases of popular actions on GitHub by giving `-d` flag.

Detecting new release and updating `popular_actions.go` are run weekly on CI by [`generate`](.github/workflows/generate.yaml)
workflow. Runs can be checked [here](https://github.com/rhysd/actionlint/actions/workflows/generate.yaml).

## Maintain `all_webhooks.go`

[`all_webhooks.go`](./all_webhooks.go) is a table all webhooks supported by GitHub Actions to trigger workflows. Note that
not all webhooks are supported by GitHub Actions.

It is generated automatically with `go generate`. The command runs [`generate-webhook-events`](./scripts/generate-webhook-events)
script.

It fetches [`events-that-trigger-workflows.md`](https://github.com/github/docs/blob/main/content/actions/learn-github-actions/events-that-trigger-workflows.md),
parses the markdown document, and extracts webhook names and their types. For more details, see
[README.md at the script](./scripts/generate-webhook-events/README.md).

Updating `all_webhooks.go` is run weekly on CI by [`generate`](.github/workflows/generate.yaml) workflow.

## Maintain `actionlint-matcher.json`

[`actionlint-matcher.json`](.github/actionlint-matcher.json) is a matcher configuration to extract error annotations from outputs
of `actionlint` command. See [the document](docs/usage.md#problem-matchers) for its usage.

The regular expression is complicated because it can matches to outputs which contain ANSI color escape sequences. So the JSON
file is not modified manually.

It is generated by [`generate-actionlint-matcher`](./scripts/generate-actionlint-matcher) script. See the README.md file for the
usage of the script and how to run the tests for it.

## Maintain `availability.go`

[`availability.go`](./availability.go) is a table for conversion from workflow key (like `jobs.<job_id>.if`) to availability of
contexts and special functions. GitHub Actions limits contexts and functions in certain places. For example:

- limited workflow keys can access `secrets` context
- `jobs.<job_id>.if` and `jobs.<job_id>.steps.if` can use `always()` function.

`availability.go` is generated from [the contexts document](https://github.com/github/docs/blob/main/content/actions/learn-github-actions/contexts.md#context-availability)
using [generate-availability](./scripts/generate-availability) script. It is run through `go generate` in `rule_expression.go`.
See [the readme of the script](./scripts/generate-availability/README.md) for the usage of the script.

Update for `availability.go` is run weekly on CI by [`generate`](.github/workflows/generate.yaml) workflow.

## Testing

- All examples in ['Checks' section](docs/checks.md) are put in [the examples directory](testdata/examples) and tested in
  [`linter_test.go`](linter_test.go).
- I cloned GitHub top 1000 repositories and extracted 1400+ workflow files. And I tried actionlint with the collected workflow
  files. All bugs found while the trial were fixed and I confirmed no more false positives.

