Publish Ruby observability plugin gem#413
Publish Ruby observability plugin gem#413ccschmitz-launchdarkly wants to merge 2 commits intomainfrom
Conversation
| name: Quality Check | ||
| runs-on: ubuntu-22.04-8core-32gb | ||
| strategy: | ||
| matrix: | ||
| ruby: ['3.1', '3.3'] | ||
| defaults: | ||
| run: | ||
| working-directory: ./sdk/@launchdarkly/observability-ruby | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
| - name: Install Ruby | ||
| uses: ruby/setup-ruby@v1 | ||
| with: | ||
| ruby-version: ${{ matrix.ruby }} | ||
| bundler-cache: true | ||
| working-directory: ./sdk/@launchdarkly/observability-ruby | ||
| - name: Install dependencies | ||
| run: bundle install | ||
| - name: Test | ||
| run: bundle exec rake test | ||
| - name: Rubocop | ||
| run: bundle exec rubocop | ||
| - name: Build gem | ||
| run: gem build *.gemspec | ||
|
|
||
| e2e-rails: |
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 21 days ago
In general, to fix this issue you add a permissions: block either at the top level of the workflow (affecting all jobs that don’t override it) or per-job, and set it to the least privileges required. For a CI workflow that just checks out code and runs tests, contents: read is typically sufficient; additional scopes (like pull-requests: write) are only needed if the workflow posts statuses/comments or modifies GitHub resources.
For this specific workflow, none of the build, e2e-rails, or e2e-rails-api-only jobs perform write operations via the GitHub API; they only read the repository, install gems, run tests, lint, and build a gem locally. Therefore, we can safely define a single root-level permissions block that applies to all jobs. The best minimal fix is to insert:
permissions:
contents: readafter the on: block and before concurrency:. This keeps existing behavior unchanged while explicitly constraining GITHUB_TOKEN to read-only repository contents.
No new imports, methods, or definitions are required; this is a pure workflow configuration change within .github/workflows/ruby-plugin.yml.
| @@ -9,6 +9,9 @@ | ||
| - 'sdk/@launchdarkly/observability-ruby/**' | ||
| - '.github/workflows/ruby-plugin.yml' | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| concurrency: ${{ github.workflow }}-${{ github.ref }} | ||
| jobs: | ||
| build: |
| name: Rails E2E Tests | ||
| runs-on: ubuntu-22.04-8core-32gb | ||
| defaults: | ||
| run: | ||
| working-directory: ./e2e/ruby/rails/demo | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
| - name: Install Ruby | ||
| uses: ruby/setup-ruby@v1 | ||
| with: | ||
| ruby-version: '3.3' | ||
| bundler-cache: true | ||
| working-directory: ./e2e/ruby/rails/demo | ||
| - name: Install dependencies | ||
| run: bundle install | ||
| - name: Test | ||
| run: bundle exec rake | ||
| - name: Rubocop | ||
| run: bundle exec rubocop | ||
|
|
||
| e2e-rails-api-only: |
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 21 days ago
In general, to fix this issue you should explicitly define a permissions block either at the workflow root (so it applies to all jobs by default) or inside each job, and set it to the minimal required scope, typically contents: read for build/test workflows. This documents the intended access and prevents accidental elevation if repository/org defaults change.
For this specific workflow, none of the jobs (build, e2e-rails, e2e-rails-api-only) perform any write operation to the repository or other GitHub resources; they only need to read the repository contents via actions/checkout. The best minimal fix is to add a root-level permissions block right after the name: (or before on:) setting contents: read. This will apply to all jobs and keep the YAML simple.
Concretely, in .github/workflows/ruby-plugin.yml, insert:
permissions:
contents: readbetween the existing name: Ruby Observability Plugin line and the on: block. No additional imports or dependencies are needed, and no job-level changes are required because the root-level permissions cover all jobs that don’t override them.
| @@ -1,5 +1,8 @@ | ||
| name: Ruby Observability Plugin | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| on: | ||
| push: | ||
| branches: ['main'] |
| name: Rails API-Only E2E Tests | ||
| runs-on: ubuntu-22.04-8core-32gb | ||
| defaults: | ||
| run: | ||
| working-directory: ./e2e/ruby/rails/api-only | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
| - name: Install Ruby | ||
| uses: ruby/setup-ruby@v1 | ||
| with: | ||
| ruby-version: '3.3' | ||
| bundler-cache: true | ||
| working-directory: ./e2e/ruby/rails/api-only | ||
| - name: Install dependencies | ||
| run: bundle install | ||
| - name: Test | ||
| run: bundle exec rake |
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 21 days ago
In general, fix this by adding an explicit permissions block that limits GITHUB_TOKEN to only the scopes needed. Here, all three jobs (build, e2e-rails, e2e-rails-api-only) only read repository contents via actions/checkout and then run local commands, so contents: read at the workflow level is sufficient and preserves existing behavior.
The best single change, without altering functionality, is to add a root-level permissions: block (applies to all jobs lacking their own permissions blocks) right after the on: section. Specifically, in .github/workflows/ruby-plugin.yml, between lines 11 and 12, insert:
permissions:
contents: readThis constrains the GITHUB_TOKEN used by actions/checkout@v4 and any other steps to read-only repository contents while keeping everything else intact. No imports, methods, or additional definitions are needed.
| @@ -9,6 +9,9 @@ | ||
| - 'sdk/@launchdarkly/observability-ruby/**' | ||
| - '.github/workflows/ruby-plugin.yml' | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| concurrency: ${{ github.workflow }}-${{ github.ref }} | ||
| jobs: | ||
| build: |
| with: | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
| - name: Install Ruby | ||
| uses: ruby/setup-ruby@v1 |
There was a problem hiding this comment.
An action sourced from a third-party repository on GitHub is not pinned to a full length commit SHA. Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload.
🥳 Removed in commit 95935a4 🥳
| with: | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
| - name: Install Ruby | ||
| uses: ruby/setup-ruby@v1 |
There was a problem hiding this comment.
An action sourced from a third-party repository on GitHub is not pinned to a full length commit SHA. Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload.
🚀 Removed in commit 95935a4 🚀
| with: | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
| - name: Install Ruby | ||
| uses: ruby/setup-ruby@v1 |
There was a problem hiding this comment.
An action sourced from a third-party repository on GitHub is not pinned to a full length commit SHA. Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload.
🧹 Removed in commit 95935a4 🧹
| working-directory: ${{ inputs.workspace-path }} | ||
|
|
||
| - name: Get RubyGems API key | ||
| uses: launchdarkly/gh-actions/actions/release-secrets@release-secrets-v1.2.0 |
There was a problem hiding this comment.
An action sourced from a third-party repository on GitHub is not pinned to a full length commit SHA. Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload.
🎈 Removed in commit 95935a4 🎈
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Install Ruby | ||
| uses: ruby/setup-ruby@v1 |
There was a problem hiding this comment.
An action sourced from a third-party repository on GitHub is not pinned to a full length commit SHA. Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload.
🍰 Removed in commit 95935a4 🍰
Fix the SSM parameter path for the RubyGems API key to match the known-working path used by ruby-server-sdk (api_key not token), and add SLSA provenance documentation for the Ruby gem.
| with: | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
| - name: Install Ruby | ||
| uses: ruby/setup-ruby@v1 |
There was a problem hiding this comment.
Semgrep identified an issue in your code:
An action sourced from a third-party repository on GitHub is not pinned to a full length commit SHA. Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload.
To resolve this comment:
✨ Commit Assistant fix suggestion
| uses: ruby/setup-ruby@v1 | |
| uses: ruby/setup-ruby@4fd86e9f50af86b19ad0bb74fba32503353e8dd3 # pinned to commit SHA for security |
View step-by-step instructions
- Replace
uses: ruby/setup-ruby@v1with a reference that pins the action to a specific full-length commit SHA. You can find the latest SHA forruby/setup-rubyin the repository's GitHub Releases or by checking https://github.com/ruby/setup-ruby/tags. - Update each occurrence, for example:
uses: ruby/setup-ruby@<commit-SHA>where<commit-SHA>is the full 40-character SHA. For example:uses: ruby/setup-ruby@4fd86e9f50af86b19ad0bb74fba32503353e8dd3. - Ensure the line does not use only a tag like
@v1or@v1.172.0, as tags can be changed or moved, while SHAs ensure immutability and prevent attackers from altering the workflow by changing action code.
Using a full commit SHA ensures the exact same version of the action is always used, protecting your workflows from unexpected changes or malicious updates.
💬 Ignore this finding
Reply with Semgrep commands to ignore this finding.
/fp <comment>for false positive/ar <comment>for acceptable risk/other <comment>for all other reasons
Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by third-party-action-not-pinned-to-commit-sha.
You can view more details about this finding in the Semgrep AppSec Platform.
| with: | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
| - name: Install Ruby | ||
| uses: ruby/setup-ruby@v1 |
There was a problem hiding this comment.
Semgrep identified an issue in your code:
An action sourced from a third-party repository on GitHub is not pinned to a full length commit SHA. Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload.
To resolve this comment:
✨ Commit Assistant fix suggestion
| uses: ruby/setup-ruby@v1 | |
| # Pinning to a specific commit SHA for security per Semgrep recommendation. | |
| uses: ruby/setup-ruby@4f4918cfaa48f36f02ea025fa277dccb77b4c41d |
View step-by-step instructions
- Visit the official ruby/setup-ruby GitHub action repository: https://github.com/ruby/setup-ruby/releases.
- Find the commit SHA for the version or release you want to use (for example, the latest v1 release). You can get this SHA from the "Commits" section or from the release tag details.
- Replace
ruby/setup-ruby@v1with the pinned format:ruby/setup-ruby@<FULL_SHA>, inserting the full commit SHA you obtained. For example:uses: ruby/setup-ruby@a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0 - Make the same replacement for every instance of
ruby/setup-ruby@v1elsewhere in your workflow files.
By pinning to a specific commit SHA, you ensure the action can't be silently changed by the repository owner or a malicious actor.
💬 Ignore this finding
Reply with Semgrep commands to ignore this finding.
/fp <comment>for false positive/ar <comment>for acceptable risk/other <comment>for all other reasons
Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by third-party-action-not-pinned-to-commit-sha.
You can view more details about this finding in the Semgrep AppSec Platform.
| with: | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
| - name: Install Ruby | ||
| uses: ruby/setup-ruby@v1 |
There was a problem hiding this comment.
Semgrep identified an issue in your code:
An action sourced from a third-party repository on GitHub is not pinned to a full length commit SHA. Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload.
To resolve this comment:
✨ Commit Assistant fix suggestion
| uses: ruby/setup-ruby@v1 | |
| # Pinned to specific commit SHA for setup-ruby v1. Update periodically for security & bugfixes. | |
| uses: ruby/setup-ruby@a9d7722c7c55796164a6e5bcfbe5bfad4f5a017f |
View step-by-step instructions
- Replace
uses: ruby/setup-ruby@v1with a specific commit SHA from the ruby/setup-ruby repository. For example:uses: ruby/setup-ruby@a9d7722c7c55796164a6e5bcfbe5bfad4f5a017f - Obtain the latest commit SHA from the relevant release by visiting https://github.com/ruby/setup-ruby/tags or the GitHub repository's commits page.
- Update all instances of
ruby/setup-ruby@v1in your workflow files to use the full commit SHA.
For example:uses: ruby/setup-ruby@a9d7722c7c55796164a6e5bcfbe5bfad4f5a017f - Ensure you update the SHA periodically to keep receiving upstream updates and bug/security fixes.
Pinning to a full commit SHA ensures that your workflow always uses the expected version of the action and protects against supply chain attacks.
💬 Ignore this finding
Reply with Semgrep commands to ignore this finding.
/fp <comment>for false positive/ar <comment>for acceptable risk/other <comment>for all other reasons
Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by third-party-action-not-pinned-to-commit-sha.
You can view more details about this finding in the Semgrep AppSec Platform.
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Install Ruby | ||
| uses: ruby/setup-ruby@v1 |
There was a problem hiding this comment.
Semgrep identified an issue in your code:
An action sourced from a third-party repository on GitHub is not pinned to a full length commit SHA. Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload.
To resolve this comment:
✨ Commit Assistant fix suggestion
| uses: ruby/setup-ruby@v1 | |
| uses: ruby/setup-ruby@5949c940b60e6b321d6e958dd42d9c7c1f72b08f # Pinned to latest stable SHA as recommended for security |
View step-by-step instructions
- Replace
uses: ruby/setup-ruby@v1with a specific, full-length commit SHA from the ruby/setup-ruby repository.
For example, change it touses: ruby/setup-ruby@5949c940b60e6b321d6e958dd42d9c7c1f72b08f(get the most recent stable SHA from https://github.com/ruby/setup-ruby/tags or from their releases). - Ensure the line now reads:
uses: ruby/setup-ruby@<commit-sha>, replacing<commit-sha>with the actual full commit SHA.
Pinning the action to a full commit SHA protects you from upstream changes or compromises in the repository.
💬 Ignore this finding
Reply with Semgrep commands to ignore this finding.
/fp <comment>for false positive/ar <comment>for acceptable risk/other <comment>for all other reasons
Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by third-party-action-not-pinned-to-commit-sha.
You can view more details about this finding in the Semgrep AppSec Platform.
Summary
Adds the full CI and release pipeline for the
launchdarkly-observabilityRuby gem (sdk/@launchdarkly/observability-ruby), bringing it in line with the existing Python, .NET, and Android plugin publish workflows.release-please-config.jsonand.release-please-manifest.jsonso version bumps and changelogs are automated. Adds ax-release-please-versionmarker toversion.rb..github/actions/publish-ruby-sdk/composite action (gem build, SLSA provenance hashing, gem push via AWS SSM-managed RubyGems key). Wires it into bothrelease-please.yml(automated releases) andmanual-publish.yml(manual trigger)..github/workflows/ruby-plugin.ymlwith quality checks (tests + RuboCop on Ruby 3.1 and 3.3) and E2E tests against the Rails demo and API-only example apps.Relates to O11Y-1150.
How did you test this change?
python-plugin.ymland the existingruby.yml(highlight-ruby)Are there any deployment considerations?
/production/common/releasing/rubygems/tokenmust be provisioned in AWS before the first publish. Alternatively, the existingRUBYGEMS_API_KEYrepo secret (used by highlight-ruby) can be used if the action is updated to reference it directly.launchdarkly-observabilitymust be claimed on rubygems.org under the LD org before the first release.