├── .github ├── CODEOWNERS ├── FUNDING.yml ├── dependabot.yml └── workflows │ └── release.yml ├── CONTRIBUTING.md ├── SECURITY.md ├── .pre-commit-config.yaml ├── LICENSE ├── action.yml ├── CODE_OF_CONDUCT.md └── README.md /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @jidicula 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: jidicula 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute: 2 | 3 | Submit a PR with your changes. It's helpful if you fork the test repo too, and demonstrate what your change does: https://github.com/jidicula/test-go-fuzz-action/pull/2 . 4 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | | Version | Supported | 6 | | ------- | ------------------ | 7 | | 1.x.x | :white_check_mark: | 8 | 9 | ## Reporting a Vulnerability 10 | 11 | Send an email to the address on my profile, subject `go-fuzz-action SECURITY`. 12 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/pre-commit/pre-commit-hooks 3 | rev: v4.0.1 4 | hooks: 5 | - id: check-yaml 6 | - id: end-of-file-fixer 7 | - id: trailing-whitespace 8 | - id: check-merge-conflict 9 | - id: mixed-line-ending 10 | - id: check-added-large-files 11 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | # Maintain dependencies for GitHub Actions 4 | - package-ecosystem: "github-actions" 5 | directory: "/" 6 | schedule: 7 | interval: "weekly" 8 | day: "saturday" 9 | time: "06:00" 10 | timezone: "America/Toronto" 11 | open-pull-requests-limit: 99 12 | commit-message: 13 | prefix: "build: " 14 | assignees: 15 | - "jidicula" 16 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | # Sequence of patterns matched against refs/tags 4 | tags: 5 | - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 6 | 7 | name: Create Release 8 | 9 | jobs: 10 | build: 11 | name: Create Release 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Checkout code 15 | uses: actions/checkout@v6 16 | with: 17 | fetch-depth: 0 18 | - name: Release with Notes 19 | uses: softprops/action-gh-release@v2 20 | with: 21 | draft: true 22 | env: 23 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Johanan Idicula 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: "Go fuzz test" 2 | description: "A GitHub Action for running go test -fuzz." 3 | 4 | branding: 5 | icon: "check-circle" 6 | color: "green" 7 | 8 | inputs: 9 | packages: 10 | description: 'Run fuzz test on these packages. Corresponds to the `[packages]` input for the `go test` command.' 11 | required: false 12 | default: '.' 13 | fuzz-regexp: 14 | description: 'Run the fuzz test matching the regular expression. Corresponds to the `-fuzz` flag for the `go test` command.' 15 | required: false 16 | default: 'Fuzz' 17 | fuzz-time: 18 | description: 'Fuzz target iteration duration, specified as a `time.Duration` (for example `1h30s`). Corresponds to `-fuzztime` flag for the `go test` command. Ensure this is less than your job timeout.' 19 | required: true 20 | fuzz-minimize-time: 21 | description: 'Fuzz minimization duration, specified as a `time.Duration` (for example `1h30s`). Corresponds to `-fuzzminimizetime` flag for the `go test` command. If you provide this input, ensure it is less than your job timeout.' 22 | required: false 23 | default: '10s' 24 | go-version: 25 | description: 'Which version of Go to use for fuzzing' 26 | required: false 27 | default: '1.21' 28 | 29 | runs: 30 | using: 'composite' 31 | steps: 32 | - uses: actions/checkout@v6 33 | - uses: actions/setup-go@v6 34 | with: 35 | go-version: '${{ inputs.go-version }}' 36 | - shell: bash 37 | run: go test "${{ inputs.packages }}" -fuzz="${{ inputs.fuzz-regexp }}" -fuzztime="${{ inputs.fuzz-time }}" -fuzzminimizetime="${{ inputs.fuzz-minimize-time }}" 38 | - name: Upload fuzz failure seed corpus as run artifact 39 | if: failure() 40 | uses: actions/upload-artifact@v6 41 | with: 42 | name: testdata 43 | path: testdata 44 | - run: echo "EVENT NAME IS ${{ github.event_name }}" 45 | if: failure() 46 | shell: bash 47 | 48 | - name: Save PR head commit SHA 49 | if: failure() && github.event_name == 'pull_request' 50 | shell: bash 51 | run: | 52 | SHA="${{ github.event.pull_request.head.sha }}" 53 | echo "SHA=$SHA" >> $GITHUB_ENV 54 | - name: Save latest commit SHA if not PR 55 | if: failure() && github.event_name != 'pull_request' 56 | shell: bash 57 | run: echo "SHA=${{ github.sha }}" >> $GITHUB_ENV 58 | 59 | - name: Output message 60 | if: failure() 61 | shell: bash 62 | run: | 63 | MESSAGE='Fuzz test failed on commit ${{ env.SHA }}. To troubleshoot locally, use the [GitHub CLI](https://cli.github.com) to download the seed corpus with\n```\ngh run download ${{ github.run_id }} -n testdata\n```' 64 | DEEPLINK="https://github.com/${{ github.repository }}/commit/${{ env.SHA }}" 65 | echo -e "${MESSAGE/${{ env.SHA }}/$DEEPLINK}" 66 | echo -e "${MESSAGE/${{ env.SHA }}/[${GITHUB_SHA:0:8}]($DEEPLINK)}" >> $GITHUB_STEP_SUMMARY 67 | - name: Report failure 68 | uses: actions/github-script@v8 69 | if: failure() && github.event_name == 'pull_request' 70 | with: 71 | script: | 72 | github.rest.issues.createComment({ 73 | issue_number: context.issue.number, 74 | owner: context.repo.owner, 75 | repo: context.repo.repo, 76 | body: 'Fuzz test failed on commit ${{ env.SHA }}. To troubleshoot locally, use the [GitHub CLI](https://cli.github.com) to download the seed corpus with\n```\ngh run download ${{ github.run_id }} -n testdata\n```' 77 | }) 78 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at johanan@forcepush.tech. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # go-fuzz-action 2 | GitHub Action for Go fuzz testing. This Action runs Go's built-in fuzz testing, added in Go 1.18, on your code. 3 | 4 | 5 | ## Do you find this useful? 6 | 7 | You can sponsor me [here](https://github.com/sponsors/jidicula)! 8 | 9 | ## Inputs 10 | * `fuzz-time` [**REQUIRED**]: Fuzz target iteration duration, specified as a `time.Duration` (for example `1h30s`). Corresponds to `-fuzztime` flag for the `go test` command. **Ensure this is less than your job/workflow timeout**. 11 | * `packages` [optional]: Run fuzz test on these packages. Corresponds to the `[packages]` input for the `go test` command. 12 | * Default: `.` 13 | * `fuzz-regexp` [optional]: Run the fuzz test matching the regular expression. Corresponds to the `-fuzz` flag for the `go test` command. 14 | * Default: `Fuzz` 15 | * `fuzz-minimize-time` [optional]: Fuzz minimization duration, specified as a `time.Duration` (for example `1h30s`). Corresponds to `-fuzzminimizetime` flag for the `go test` command. If you provide this input, ensure it is less than your job timeout. 16 | * Default: `10s` 17 | * `go-version` [optional]: Which version of Go to use for fuzzing. This will be passed on to `actions/setup-go@v3`. 18 | * Default: `1.18` 19 | 20 | ## Returns: 21 | * SUCCESS: if your fuzz tests don't raise a failure within the `fuzz-time` input constraint. 22 | * FAILURE: if your fuzz tests raise a failure within the `fuzz-time` input constraint. 23 | * The workflow run logs will include instructions on how to download (using the [GitHub CLI](https://cli.github.com)) the failing seed corpus to your local machine for remediation, regardless of run trigger. 24 | * If you run this Action in a PR workflow, it'll comment these instructions on your PR: image 25 | 26 | # Usage 27 | ⚠️This Action is not tested on `windows` GitHub Actions runners! Use with `windows` runner OS at your own risk! 28 | 29 | Create a `.github/workflows/go-fuzz-test.yml` in your repository containing: 30 | 31 | 32 | ```yaml 33 | name: Go fuzz test 34 | on: 35 | push: 36 | pull_request: 37 | jobs: 38 | fuzz-test: 39 | name: Fuzz test 40 | runs-on: ubuntu-latest 41 | steps: 42 | - uses: jidicula/go-fuzz-action@v1.1.0 43 | with: 44 | fuzz-time: 30s 45 | ``` 46 | 47 | ## Fuzz test all packages in repo 48 | 49 | If you have multiple packages in your repo and you want to fuzz test them all, create a `.github/workflows/go-fuzz-test.yml` in your repository containing: 50 | 51 | ```yaml 52 | name: Go fuzz test 53 | on: 54 | push: 55 | pull_request: 56 | jobs: 57 | fuzz-test: 58 | name: Fuzz test 59 | runs-on: ubuntu-latest 60 | steps: 61 | - uses: jidicula/go-fuzz-action@v1.1.0 62 | with: 63 | packages: './...' 64 | fuzz-time: 30s 65 | ``` 66 | 67 | ## Longer minimize time 68 | 69 | If you want the fuzz test to spend more time on minimizing the failing input to the smallest possible and most human readable value which will still produce an error, create a `.github/workflows/go-fuzz-test.yml` in your repository containing: 70 | 71 | ```yaml 72 | name: Go fuzz test 73 | on: 74 | push: 75 | pull_request: 76 | jobs: 77 | fuzz-test: 78 | name: Fuzz test 79 | runs-on: ubuntu-latest 80 | steps: 81 | - uses: jidicula/go-fuzz-action@v1.1.0 82 | with: 83 | packages: './...' 84 | fuzz-time: 30s 85 | fuzz-minimize-time: 1m 86 | ``` 87 | 88 | ## Fuzz tests with different regexp 89 | 90 | If you have fuzz tests that don't begin with `Fuzz` (the default regexp), create a `.github/workflows/go-fuzz-test.yml` in your repository containing: 91 | 92 | ```yaml 93 | name: Go fuzz test 94 | on: 95 | push: 96 | pull_request: 97 | jobs: 98 | fuzz-test: 99 | name: Fuzz test 100 | runs-on: ubuntu-latest 101 | steps: 102 | - uses: jidicula/go-fuzz-action@main 103 | with: 104 | packages: './...' 105 | fuzz-time: 30s 106 | fuzz-minimize-time: 1m 107 | fuzz-regexp: OtherFuzzRegexp 108 | ``` 109 | 110 | # Example repo 111 | 112 | I haven't figured out how to test this adequately within this repo, so you can verify its behaviour here: https://github.com/jidicula/test-go-fuzz-action/pull/2 113 | 114 | # Who uses this? 115 | 116 | [These public repos](https://github.com/search?o=desc&q=uses%3A+jidicula%2Fgo-fuzz-action+-user%3Ajidicula&s=indexed&type=Code) use this Action. 117 | --------------------------------------------------------------------------------