{"id":14956024,"url":"https://github.com/envylabs/rapporteur","last_synced_at":"2025-12-16T18:34:05.427Z","repository":{"id":46234318,"uuid":"10064614","full_name":"envylabs/rapporteur","owner":"envylabs","description":"A Rails Engine which provides a customizable status page on your application.","archived":false,"fork":false,"pushed_at":"2025-08-30T14:07:46.000Z","size":366,"stargazers_count":49,"open_issues_count":0,"forks_count":5,"subscribers_count":15,"default_branch":"main","last_synced_at":"2025-10-19T11:57:43.666Z","etag":null,"topics":["rails","ruby","ruby-gem","ruby-on-rails"],"latest_commit_sha":null,"homepage":"http://rubygems.org/gems/rapporteur","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/envylabs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2013-05-14T20:49:27.000Z","updated_at":"2025-08-30T14:07:49.000Z","dependencies_parsed_at":"2024-06-19T23:52:20.683Z","dependency_job_id":"d2e6301f-76da-4b66-bebd-af88f30dc25f","html_url":"https://github.com/envylabs/rapporteur","commit_stats":{"total_commits":464,"total_committers":10,"mean_commits":46.4,"dds":0.5237068965517242,"last_synced_commit":"10b2bec8f065f0459ee9844412147689b76cfeaa"},"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"purl":"pkg:github/envylabs/rapporteur","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/envylabs%2Frapporteur","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/envylabs%2Frapporteur/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/envylabs%2Frapporteur/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/envylabs%2Frapporteur/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/envylabs","download_url":"https://codeload.github.com/envylabs/rapporteur/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/envylabs%2Frapporteur/sbom","scorecard":{"id":378492,"data":{"date":"2025-08-11","repo":{"name":"github.com/envylabs/rapporteur","commit":"d1ff53c0733403430eb97f3dbfd55178bc7ac17d"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.1,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"1 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/25 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: jobLevel 'contents' permission set to 'write': .github/workflows/release-please.yml:9","Warn: jobLevel 'contents' permission set to 'write': .github/workflows/release-please.yml:24","Warn: no topLevel permission defined: .github/workflows/release-please.yml:1","Warn: no topLevel permission defined: .github/workflows/tests.yml:1"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: third-party GitHubAction not pinned by hash: .github/workflows/release-please.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/envylabs/rapporteur/release-please.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release-please.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/envylabs/rapporteur/release-please.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release-please.yml:30: update your workflow using https://app.stepsecurity.io/secureworkflow/envylabs/rapporteur/release-please.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release-please.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/envylabs/rapporteur/release-please.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yml:9: update your workflow using https://app.stepsecurity.io/secureworkflow/envylabs/rapporteur/tests.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/tests.yml:10: update your workflow using https://app.stepsecurity.io/secureworkflow/envylabs/rapporteur/tests.yml/main?enable=pin","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   4 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.txt:0","Info: FSF or OSI recognized license: MIT License: LICENSE.txt:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v3.8.0 not signed: https://api.github.com/repos/envylabs/rapporteur/releases/57783893","Warn: release artifact v3.7.1 not signed: https://api.github.com/repos/envylabs/rapporteur/releases/31816156","Warn: release artifact v3.7.0 not signed: https://api.github.com/repos/envylabs/rapporteur/releases/31816203","Warn: release artifact v3.6.4 not signed: https://api.github.com/repos/envylabs/rapporteur/releases/16563078","Warn: release artifact v3.8.0 does not have provenance: https://api.github.com/repos/envylabs/rapporteur/releases/57783893","Warn: release artifact v3.7.1 does not have provenance: https://api.github.com/repos/envylabs/rapporteur/releases/31816156","Warn: release artifact v3.7.0 does not have provenance: https://api.github.com/repos/envylabs/rapporteur/releases/31816203","Warn: release artifact v3.6.4 does not have provenance: https://api.github.com/repos/envylabs/rapporteur/releases/16563078"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 5 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T14:49:04.668Z","repository_id":46234318,"created_at":"2025-08-18T14:49:04.669Z","updated_at":"2025-08-18T14:49:04.669Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280911349,"owners_count":26412209,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-25T02:00:06.499Z","response_time":81,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["rails","ruby","ruby-gem","ruby-on-rails"],"created_at":"2024-09-24T13:12:11.961Z","updated_at":"2025-11-11T18:40:20.352Z","avatar_url":"https://github.com/envylabs.png","language":"Ruby","readme":"# Rapporteur (rap-or-TUHR)\n\n[![Gem Version](https://badge.fury.io/rb/rapporteur.svg)](https://badge.fury.io/rb/rapporteur)\n[![Tests](https://github.com/envylabs/rapporteur/actions/workflows/tests.yml/badge.svg)](https://github.com/envylabs/rapporteur/actions/workflows/tests.yml)\n\n\nThis gem provides a singular, status-checking endpoint to your application. The\nendpoint provides a JSON response with either an HTTP 200 or an HTTP 500\nresponse, depending on the current application environment.\n\nWhen the environment tests successfully, an HTTP 200 response is returned with\nthe current application Git revision and server time:\n\n```json\n{\n  \"revision\": \"906731e6467ea381ba5bc70f103b85ed4178fee7\",\n  \"time\": \"2013-05-19T05:38:46Z\"\n}\n```\n\nWhen an application validation fails, an HTTP 500 response is returned with a\ncollection of error messages, similar to the Rails \u003c 4.2 responders for model\nvalidations:\n\n```json\n{\n  \"errors\": {\n    \"database\": [\"The application database is inaccessible or unavailable\"]\n  }\n}\n```\n\n## Installation\n\nTo install, add this line to your application's Gemfile:\n\n```ruby\ngem 'rapporteur'\n```\n\nAnd then execute:\n\n```bash\n$ bundle install\n```\n\n### Supported environments\n\nThis library follows the maintenance policy of\n[Ruby](https://www.ruby-lang.org/en/downloads/branches/),\n[Ruby on Rails](https://guides.rubyonrails.org/maintenance_policy.html), and\n[Sinatra](https://github.com/sinatra/sinatra/blob/master/MAINTENANCE.md) for\ntesting and maintaining these environments.\n\nUnsupported versions of Ruby, Ruby on Rails, or Sinatra may also work with this\nlibrary, however they are not officially supported or tested against.\n\n## Usage\n\nBy default, there are no application checks that run and the status endpoint\nsimply reports the current application revision and time. This is useful for a\nbasic connectivity check to be watched by a third party service like Pingdom\nfor a very simple, non-critical application.\n\nYou may optionally use any of the pre-defined checks (such as the ActiveRecord\nconnection check) to expand the robustness of the status checks. Adding a check\nwill execute that check each time the status endpoint is requested, so be\nsomewhat wary of doing _too_ much. See more in the [Adding checks\nsection](#adding-checks), below.\n\nFurther, you can define your own checks which could be custom to your\napplication or environment and report their own, unique errors.  The only\nrequirement is that the check objects are callable (respond to `#call`, like a\nProc). See more in the [Creating custom checks\nsection](#creating-custom-checks), below.\n\n### Usage in a Rails application\n\nIf you're running in a Rails environment, then the included Rails Engine should\nautomatically get required and loaded. However, you will need to instruct your\napplication where to mount the status endpoint. In your `config/routes.rb`, add\na `mount` at the endpoint you desire:\n\n```ruby\nRails.application.routes.draw do\n  mount Rapporteur::Engine, at: '/status'\nend\n```\n\nThis will mount the Rapporteur status endpoint at `/status` where it will\nlisten for and respond to JSON requests (`/status.json`, for example).\n\n### Usage in a Rack (non-Rails) application\n\nIf you're running in a non-Rails, Rack environment (e.g. Sinatra), you can\n`require \"rapporteur\"` and use the status generator directly from your own\nendpoints.\n\nSo, here is an example usage in Sinatra:\n\n```ruby\nrequire 'rapporteur'\nrequire 'sinatra/base'\n\nclass MyApp \u003c Sinatra::Base\n  get '/status.json' do\n    content_type :json\n    status(result.errors.empty? ? 200 : 500)\n    body Rapporteur.run.as_json.to_json\n  end\nend\n```\n\nRequire `rapporteur` and then, at some point, call `Rapporteur.run` to execute\nthe configured checks. `as_json` will convert the result of the `run` into a\nHash which is ready for JSON generation. At that point, do whatever you need to\ndo with the Hash to have your framework of choice generate and respond with\nJSON.\n\n## Customization\n\n### Adding checks\n\nThis gem ships with the following checks tested and packaged:\n\n* **Rapporteur::Checks::ActiveRecordCheck** - Performs a trivial test\n  of the current `ActiveRecord::Base.connection` to ensure basic database\n  connectivity.\n\nTo add checks to your application, define the checks you'd like to run in your\nenvironment or application configuration files or initializers, such as:\n\n```ruby\n# config/initializers/rapporteur.rb\nRapporteur.add_check(Rapporteur::Checks::ActiveRecordCheck)\n```\n\nOr, make an environment specific check with:\n\n```ruby\n# config/environments/production.rb\nMyApplication.configure do\n  config.to_prepare do\n    Rapporteur.add_check(Rapporteur::Checks::ActiveRecordCheck)\n  end\nend\n```\n\n### Creating custom checks\n\nIt is simple to add a custom check to the status endpoint. All that is required\nis that you give the checker an object that is callable. In your object, simply\ncheck for the state of the world that you're interested in, and if you're not\nhappy with it, add an error to the given `checker` instance:\n\n```ruby\n# config/initializers/rapporteur.rb\n\n# Define a simple check as a block:\nRapporteur.add_check do |checker|\n  checker.add_message(:paid, 'too much')\nend\n\n# Make and use a reusable Proc or lambda:\nmy_proc_check = lambda { |checker|\n  checker.add_error(:luck, :bad) if rand(2) \u003e 0\n  checker.add_message(:luck, :good)\n}\nRapporteur.add_check(my_proc_check)\n\n# Package a check into a Class:\nclass MyClassCheck\n  def self.call(checker)\n    @@counter ||= 0\n    checker.add_error(:count, :exceeded) if @@counter \u003e 50\n  end\nend\nRapporteur.add_check(MyClassCheck)\n```\n\nCertainly, the definition and registration of the checks do not need to occur\nwithin the same file, but you get the idea. Also: Please make your checks more\nuseful than those defined above. ;)\n\nYou could create a checker for your active Redis connection, Memcached\nconnections, disk usage percentage, process count, memory usage, or really\nanything you like. Again, because these checks get executed every time the\nstatus endpoint is called, **be mindful of the tradeoffs when making a check that\nmay be resource intensive**.\n\n### Customizing the revision\n\nIf you need to customize the way in which the current application revision is\ncalculated (by default it runs a `git rev-parse HEAD`), you may do so by\nmodifying the necessary environment file or creating an initializer in your\nRails application:\n\n```ruby\n# config/initializers/rapporteur.rb\nRapporteur::Revision.current = 'revision123'\n```\n\n```ruby\n# config/environments/production.rb\nMyApplication.configure do\n  config.to_prepare do\n    Rapporteur::Revision.current = 'revision123'\n  end\nend\n```\n\nYou may pass a String or a callable object (Proc) to `.current=` and it will be\nexecuted and memoized. Useful examples of this are:\n\n```ruby\n# Read a Capistrano REVISION file\nRapporteur::Revision.current = Rails.root.join('REVISION').read.strip\n\n# Force a particular directory and use Git\nRapporteur::Revision.current = `cd \"#{Rails.root}\" \u0026\u0026 git rev-parse HEAD`.strip\n\n# Use an ENV variable (Heroku Bamboo Stack)\nRapporteur::Revision.current = ENV['REVISION']\n\n# Do some crazy calculation\nRapporteur::Revision.current = lambda { MyRevisionCalculator.execute! }\n```\n\n### Customizing the messages\n\nThe success and error messages displayed in the event that application\nvalidations pass or fail are all optionally passed through I18n. There are\ndefault localization strings provided with the gem, but you may override them\nas necessary, by simply redefining the proper locale keys in a locale file\nwithin your local application.\n\nFor example, to override the database check failure message:\n\n```yaml\n# /config/locales/en.yml\nen:\n  rapporteur:\n    errors:\n      database:\n        unavailable: \"Something went wrong\"\n```\n\nIf you created a custom checker which reports the current sky color, for\nexample, and wanted the success messages to be localized, you could do the\nfollowing:\n\n```ruby\n# /config/initializers/rapporteur.rb\nsky_check = lambda { |checker| checker.add_message(:sky, :blue) }\nRapporteur.add_check(sky_check)\n```\n\n```yaml\n# /config/locales/fr.yml\nfr:\n  rapporteur:\n    messages:\n      sky:\n        blue: \"bleu\"\n```\n\n## Contributing\n\n1. Fork it\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create new Pull Request\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fenvylabs%2Frapporteur","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fenvylabs%2Frapporteur","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fenvylabs%2Frapporteur/lists"}