├── .gitignore ├── examples ├── ruby-version-file │ ├── .ruby-version │ ├── Gemfile │ └── app.rb ├── bad │ ├── Gemfile │ └── app.rb └── good │ ├── Gemfile │ └── app.rb ├── screenshots ├── check-overview.png └── file-annotation.png ├── .github ├── dependabot.yml └── workflows │ ├── release.yml │ └── test.yml ├── RELEASE.md ├── LICENSE ├── CHANGELOG.md ├── README.md └── action.yml /.gitignore: -------------------------------------------------------------------------------- 1 | /tmp/ 2 | /.vscode/ 3 | -------------------------------------------------------------------------------- /examples/ruby-version-file/.ruby-version: -------------------------------------------------------------------------------- 1 | 3.1 2 | -------------------------------------------------------------------------------- /examples/bad/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | gem "standard" 3 | -------------------------------------------------------------------------------- /examples/good/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | gem "standard" 3 | -------------------------------------------------------------------------------- /examples/ruby-version-file/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | gem "standard" 3 | -------------------------------------------------------------------------------- /screenshots/check-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardrb/standard-ruby-action/HEAD/screenshots/check-overview.png -------------------------------------------------------------------------------- /screenshots/file-annotation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardrb/standard-ruby-action/HEAD/screenshots/file-annotation.png -------------------------------------------------------------------------------- /examples/good/app.rb: -------------------------------------------------------------------------------- 1 | # sample ruby app, passes standard ruby 2 | 3 | require "sinatra" 4 | 5 | get "/frank-says" do 6 | "Put this in your pipe & smoke it!" 7 | end 8 | -------------------------------------------------------------------------------- /examples/bad/app.rb: -------------------------------------------------------------------------------- 1 | # sample ruby app, known to not pass standard ruby 2 | 3 | require 'sinatra' 4 | 5 | get '/frank-says' do 6 | 'Put this in your pipe & smoke it!' 7 | end 8 | -------------------------------------------------------------------------------- /examples/ruby-version-file/app.rb: -------------------------------------------------------------------------------- 1 | # sample ruby app, passes standard ruby 2 | 3 | require "sinatra" 4 | 5 | get "/frank-says" do 6 | "Put this in your pipe & smoke it!" 7 | end 8 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Documentation: https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file 2 | 3 | version: 2 4 | updates: 5 | - package-ecosystem: github-actions 6 | directory: "/" 7 | schedule: { interval: weekly } 8 | - package-ecosystem: bundler 9 | directories: [ "/examples/*" ] 10 | schedule: { interval: weekly } 11 | -------------------------------------------------------------------------------- /RELEASE.md: -------------------------------------------------------------------------------- 1 | # How to release an update 2 | 3 | 1. Ensure the [changelog][] is current. 4 | 2. Create a tag (signed, preferably) in the form "v1.2.3". 5 | 3. Push the tag. 6 | 4. Monitor the [release jobs][]. 7 | - The [release workflow][] creates a [GitHub Release][] for the pushed tag. 8 | - The Release publishes the action to [GitHub Marketplace][]. 9 | - The release workflow also advances the corresponding [major version ref][]. 10 | 11 | ```console 12 | git tag -s v1.2.3 13 | git push --tags 14 | ``` 15 | 16 | [changelog]: ./CHANGELOG.md 17 | [release workflow]: .github/workflows/release.yml 18 | [github release]: https://github.com/standardrb/standard-ruby-action/releases 19 | [release jobs]: https://github.com/standardrb/standard-ruby-action/actions/workflows/release.yml 20 | [github marketplace]: https://github.com/marketplace/actions/standard-ruby-linter 21 | [major version ref]: https://github.com/standardrb/standard-ruby-action/branches/all?query=v 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024, Test Double Inc., 2019 Andrew Mason 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 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | push: { tags: "v*.*.*" } 4 | workflow_dispatch: 5 | 6 | permissions: {} 7 | 8 | jobs: 9 | # Create a GitHub Release for each pushed git-tag 10 | github: 11 | permissions: { contents: write } 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0 15 | with: { egress-policy: audit } 16 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 17 | - run: | 18 | gh release view $tag || \ 19 | gh release create ${tag/*-*/"$tag" --prerelease} --generate-notes 20 | env: 21 | GH_TOKEN: ${{ github.token }} 22 | tag: ${{ github.ref_name }} 23 | 24 | # Bump the 'vMajor' ref to latest patch|minor version 25 | vMajor-ref: 26 | if: ${{ !contains(github.ref, '-') }} # skip prereleases 27 | permissions: { contents: write } 28 | runs-on: ubuntu-latest 29 | steps: 30 | - uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0 31 | with: { egress-policy: audit } 32 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 33 | # FIXME pushes branch instead of tag because github bug: 34 | # https://github.com/orgs/community/discussions/163366 35 | - run: git push -f origin "HEAD:refs/heads/${GITHUB_REF_NAME%%.*}" 36 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Smoke Test 2 | on: # test our action against multiple events 3 | push: 4 | pull_request: 5 | workflow_dispatch: 6 | 7 | permissions: 8 | checks: write 9 | contents: write 10 | 11 | jobs: 12 | pass-standard: # uses default 'ruby' version 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 16 | - uses: ./ 17 | with: 18 | working-directory: examples/good 19 | 20 | ruby-version-param: # uses 3.2 explicitly from input param 21 | runs-on: ubuntu-latest 22 | steps: 23 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 24 | - uses: ./ 25 | with: 26 | ruby-version: 3.2 27 | workdir: examples/ruby-version-file 28 | 29 | ruby-version-file: # uses 3.1 implicitly from ruby-version file 30 | runs-on: ubuntu-latest 31 | steps: 32 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 33 | - uses: ./ 34 | with: 35 | workdir: examples/ruby-version-file 36 | 37 | fail-standard: 38 | runs-on: ubuntu-latest 39 | steps: 40 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 41 | - continue-on-error: true 42 | id: standardrb 43 | uses: ./ 44 | with: 45 | working-directory: examples/bad 46 | autofix: false 47 | - if: steps.standardrb.outcome != 'failure' 48 | run: echo "Standard should have failed"; exit 1 49 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | ## 1.5.0 4 | 5 | * Rename back to Standard Ruby by @jasonkarns in https://github.com/standardrb/standard-ruby-action/pull/31 6 | 7 | ## 1.4.1 8 | 9 | * Fix typo in README by @garyhtou in https://github.com/standardrb/standard-ruby-action/pull/24 10 | * Create Release GHA workflow by @jasonkarns in https://github.com/standardrb/standard-ruby-action/pull/27 11 | * rename action for publishing to github marketplace by @jasonkarns in https://github.com/standardrb/standard-ruby-action/pull/28 12 | 13 | ## 1.4.0 14 | 15 | * Configurable working directory [#22](https://github.com/standardrb/standard-ruby-action/pull/22) 16 | 17 | ## 1.3.0 18 | 19 | * Read .ruby-version [#20](https://github.com/standardrb/standard-ruby-action/pull/20) 20 | 21 | ## 1.2.0 22 | 23 | * Make fix optional [#18](https://github.com/standardrb/standard-ruby-action/pull/18) 24 | 25 | ## 1.1.0 26 | 27 | * Set the ruby-version 28 | 29 | ## 1.0.1 30 | 31 | * Add GitHub annotations formatting to output 32 | 33 | ## 1.0.0 34 | 35 | * Rewritten as a 'composite' workflow action 36 | 37 | ## 0.0.3 - 0.0.5 38 | 39 | * Changes lost to the sands of time, because this file wasn't kept up to date. 40 | * Feel free to review the [commit log](https://github.com/standardrb/standard-ruby-action/commits/main/) 41 | 42 | ## 0.0.2 43 | 44 | [Full Changelog](https://github.com/andrewmcodes/standardrb-action/compare/v0.0.1...v0.0.2) 45 | 46 | **Merged pull requests:** 47 | 48 | - v0.0.2 version bump [\#4](https://github.com/andrewmcodes/standardrb-action/pull/4) ([andrewmcodes](https://github.com/andrewmcodes)) 49 | - Fix unprocessable entity error when versions are present [\#3](https://github.com/andrewmcodes/standardrb-action/pull/3) ([andrewmcodes](https://github.com/andrewmcodes)) 50 | - docs: add andrewmcodes as a contributor [\#2](https://github.com/andrewmcodes/standardrb-action/pull/2) ([allcontributors[bot]](https://github.com/apps/allcontributors)) 51 | - Update issue templates [\#1](https://github.com/andrewmcodes/standardrb-action/pull/1) ([andrewmcodes](https://github.com/andrewmcodes)) 52 | 53 | ## 0.0.1 54 | 55 | * Initial release 56 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Standard Ruby GitHub Action 2 | 3 | A GitHub Action to run [Standard Ruby](https://github.com/standardrb/standard) 4 | against your code. Here's what it does: 5 | 6 | 1. Runs `bundle exec standardrb --fix` on the root directory of your repo 7 | 2. If any errors were auto-fixable, it commits those changes back to the repo 8 | 3. If any errors remain, it fails the build with annotations for each failure 9 | 10 | ## Usage 11 | 12 | ### Creating a Standard Ruby workflow: 13 | 14 | To separate Standard Ruby linting and formatting from your main test suite, you 15 | can add it in a standalone workflow: 16 | 17 | ```yaml 18 | name: Standard Ruby 19 | 20 | on: [push] 21 | 22 | jobs: 23 | build: 24 | runs-on: ubuntu-latest 25 | permissions: 26 | checks: write 27 | contents: write 28 | steps: 29 | - name: Standard Ruby 30 | uses: standardrb/standard-ruby-action@v1 31 | ``` 32 | 33 | ### Adding to an existing workflow: 34 | 35 | You can add the following to your existing GitHub Action workflow: 36 | 37 | ```yaml 38 | - name: Standard Ruby 39 | uses: standardrb/standard-ruby-action@v1 40 | ``` 41 | 42 | This will require you to add these permissions at the top-level of your workflow 43 | (for example, after specifying the operating system via `runs_on`): 44 | 45 | ```yaml 46 | runs-on: ubuntu-latest 47 | permissions: 48 | checks: write 49 | contents: read 50 | ``` 51 | 52 | ## Options 53 | 54 | - `ruby-version` - If your project has a `.ruby-version` file, this Action will use that version of Ruby. If not, this will be forwarded to the [ruby/setup-ruby](https://github.com/ruby/setup-ruby) action, so it takes the same values. 55 | - `autofix` - If set to `false`, the action will not attempt to auto-fix any errors. Defaults to `true`. 56 | - `workdir` - If set the action will descend to this directory before running `bundle exec standardrb …` and other relevant setup commands. Defaults to `.`. 57 | 58 | Example with options set: 59 | 60 | ```yaml 61 | - name: Standard Ruby 62 | uses: standardrb/standard-ruby-action@v1 63 | with: 64 | ruby-version: '3.3' 65 | autofix: false 66 | workdir: my/app/subdirectory 67 | ``` 68 | 69 | ## Screenshots 70 | 71 | **[Update 6/17/2024: the current v1 release doesn't produce annotations like 72 | this, unfortunately. See 73 | [#16](https://github.com/standardrb/standard-ruby-action/issues/16)]** 74 | 75 | ![StandardRB Action Checks Overview](screenshots/check-overview.png) 76 | ![StandardRB Action File Annotation](screenshots/file-annotation.png) 77 | 78 | ## Code of Conduct 79 | 80 | This project follows Test Double's [code of 81 | conduct](https://testdouble.com/code-of-conduct) for all community interactions, 82 | including (but not limited to) one-on-one communications, public posts/comments, 83 | code reviews, pull requests, and GitHub issues. If violations occur, Test Double 84 | will take any action they deem appropriate for the infraction, up to and 85 | including blocking a user from the organization's repositories. 86 | 87 | ## Acknowledgements 88 | 89 | A big thanks to [Andrew Mason](https://github.com/andrewmcodes) for kicking off 90 | this project as 91 | [andrewmcodes/standardrb-action](https://github.com/andrewmcodes/standardrb-action)! 92 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: Standard Ruby 2 | description: Lint and auto-fix your Ruby code with Standard Ruby. 3 | author: Justin Searls 4 | branding: { icon: code, color: yellow } 5 | 6 | inputs: 7 | ruby-version: 8 | description: > 9 | The ruby version specifier to pass to ruby/setup-ruby. If omitted, 10 | respects files (in order) — .ruby-version, .tool-versions, mise.toml. 11 | Finally defaults to 'ruby' (latest stable CRuby). 12 | https://github.com/ruby/setup-ruby?tab=readme-ov-file#supported-version-syntax 13 | required: false 14 | default: '' 15 | autofix: 16 | description: Whether autofixes should be committed back to the branch 17 | required: false 18 | default: 'true' 19 | workdir: 20 | description: The working directory from which to run this action's commands. 21 | default: '' 22 | deprecationMessage: rename to 'working-directory'. 23 | working-directory: 24 | description: The working directory from which to run this action's commands. 25 | default: '.' 26 | 27 | runs: 28 | using: composite 29 | 30 | steps: 31 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 32 | 33 | - if: ${{ inputs.ruby-version == '' }} 34 | shell: bash 35 | working-directory: ${{ inputs.workdir || inputs.working-directory }} 36 | run: | 37 | if [ -f .ruby-version ] || grep -sq ruby -- .tool-versions mise.toml; 38 | then echo "Version files found; allow setup-ruby to resolve from file." 39 | else echo "No version files found; using 'ruby' (latest stable CRuby)." 40 | echo "ruby-version=ruby" >> "$GITHUB_ENV" 41 | fi 42 | 43 | - uses: ruby/setup-ruby@ac793fdd38cc468a4dd57246fa9d0e868aba9085 # v1.270.0 44 | with: 45 | ruby-version: ${{ inputs.ruby-version || env.ruby-version }} 46 | bundler-cache: true 47 | working-directory: ${{ inputs.workdir || inputs.working-directory }} 48 | 49 | - name: Run Standard Ruby; optionally autofix 50 | id: standardrb 51 | shell: bash 52 | working-directory: ${{ inputs.workdir || inputs.working-directory }} 53 | run: bundle exec standardrb ${{ inputs.autofix == 'true' && '--fix' || '' }} --format github --format "Standard::Formatter" 54 | continue-on-error: true 55 | 56 | - name: Check for modified files 57 | id: check_changes 58 | shell: bash 59 | working-directory: ${{ inputs.workdir || inputs.working-directory }} 60 | run: | 61 | if [ -n "$(git diff --name-only --diff-filter=M)" ]; then 62 | echo "standardrb_autofixes_found=true" >> $GITHUB_ENV 63 | else 64 | echo "standardrb_autofixes_found=false" >> $GITHUB_ENV 65 | fi 66 | 67 | - name: Commit autofixes 68 | shell: bash 69 | if: env.standardrb_autofixes_found == 'true' 70 | run: | 71 | echo "::group::Committing Standard Fixes" 72 | git config --global user.name 'standard-ruby-action[bot]' 73 | git config --global user.email 'standard-ruby-action[bot]@users.noreply.github.com' 74 | # Add any files that were changed by Standard Ruby 75 | git diff --name-only --diff-filter=M | xargs git add 76 | git commit -m "Apply Standard Ruby autofixes" || echo "No changes to commit" 77 | git push 78 | echo "::endgroup::" 79 | 80 | - name: Fail the build if Standard Ruby failed 81 | shell: bash 82 | if: ${{ steps.standardrb.outcome == 'failure' }} 83 | run: | 84 | echo "::error::Standard Ruby found issues in your code." 85 | exit 1 86 | --------------------------------------------------------------------------------