Skip to content

Commit

Permalink
ci: Add release please support (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
keelerm84 committed Apr 3, 2024
1 parent 30c341f commit abee0a6
Show file tree
Hide file tree
Showing 20 changed files with 390 additions and 4 deletions.
9 changes: 9 additions & 0 deletions .github/actions/build-docs/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name: Build Documentation
description: 'Build Documentation.'

runs:
using: composite
steps:
- name: Build Documentation
shell: bash
run: cd docs && make html
25 changes: 25 additions & 0 deletions .github/actions/ci/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: CI Workflow
description: 'Shared CI workflow.'
inputs:
ruby-version:
description: 'The version of ruby to setup and run'
required: true

runs:
using: composite
steps:
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ inputs.ruby-version }}

- name: Install dependencies
shell: bash
run: bundle install

- name: Run tests
shell: bash
run: bundle exec rspec spec $SPEC_TAGS

- name: Run RuboCop
shell: bash
run: bundle exec rubocop --parallel
15 changes: 15 additions & 0 deletions .github/actions/publish-docs/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: Publish Documentation
description: 'Publish the documentation to GitHub Pages'
inputs:
token:
description: 'Token to use for publishing.'
required: true

runs:
using: composite
steps:
- uses: launchdarkly/gh-actions/actions/publish-pages@publish-pages-v1.0.1
name: 'Publish to Github pages'
with:
docs_path: docs/build/html/
github_token: ${{inputs.token}} # For the shared action the token should be a GITHUB_TOKEN<
28 changes: 28 additions & 0 deletions .github/actions/publish/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Publish Package
description: 'Publish the package to rubygems'
inputs:
dry_run:
description: 'Is this a dry run. If so no package will be published.'
required: true
outputs:
gem-hash:
description: "base64-encoded sha256 hashes of distribution files"
value: ${{ steps.gem-hash.outputs.gem-hash }}

runs:
using: composite
steps:
- name: Build gemspec
shell: bash
run: gem build launchdarkly-server-sdk-otel.gemspec

- name: Hash gem for provenance
id: gem-hash
shell: bash
run: |
echo "gem-hash=$(sha256sum launchdarkly-server-sdk-otel-*.gem | base64 -w0)" >> "$GITHUB_OUTPUT"
- name: Publish Library
shell: bash
if: ${{ inputs.dry_run == 'false' }}
run: gem push launchdarkly-server-sdk-otel-*.gem
54 changes: 54 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Run CI
on:
push:
branches: [ main ]
paths-ignore:
- '**.md' # Do not need to run CI for markdown changes.
pull_request:
branches: [ main ]
paths-ignore:
- '**.md'

jobs:
build-linux:
runs-on: ubuntu-latest

strategy:
matrix:
ruby-version:
- '3.0'
- '3.1'
- '3.2'
- jruby-9.4

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # If you only need the current version keep this.

- uses: ./.github/actions/ci
with:
ruby-version: ${{ matrix.ruby-version }}

- uses: ./.github/actions/build-docs
if: ${{ !startsWith(matrix.ruby-version, 'jruby') }}

build-windows:
runs-on: windows-latest

defaults:
run:
shell: powershell

steps:
- uses: actions/checkout@v4

- uses: ruby/setup-ruby@v1
with:
ruby-version: 3.0

- name: Install dependencies
run: bundle install

- name: Run tests
run: bundle exec rspec spec
12 changes: 12 additions & 0 deletions .github/workflows/lint-pr-title.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: Lint PR title

on:
pull_request_target:
types:
- opened
- edited
- synchronize

jobs:
lint-pr-title:
uses: launchdarkly/gh-actions/.github/workflows/lint-pr-title.yml@main
22 changes: 22 additions & 0 deletions .github/workflows/manual-publish-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
on:
workflow_dispatch:

name: Publish Documentation
jobs:
build-publish-docs:
runs-on: ubuntu-latest
permissions:
id-token: write # Needed if using OIDC to get release secrets.
contents: write # Needed in this case to write github pages.
steps:
- uses: actions/checkout@v4

- uses: ruby/setup-ruby@v1
with:
ruby-version: 3.0

- uses: ./.github/actions/build-docs

- uses: ./.github/actions/publish-docs
with:
token: ${{secrets.GITHUB_TOKEN}}
49 changes: 49 additions & 0 deletions .github/workflows/manual-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Publish Package
on:
workflow_dispatch:
inputs:
dry_run:
description: 'Is this a dry run. If so no package will be published.'
type: boolean
required: true

jobs:
build-publish:
runs-on: ubuntu-latest
# Needed to get tokens during publishing.
permissions:
id-token: write
contents: read
outputs:
gem-hash: ${{ steps.publish.outputs.gem-hash}}
steps:
- uses: actions/checkout@v4

- uses: launchdarkly/gh-actions/actions/release-secrets@release-secrets-v1.0.0
name: 'Get rubygems API key'
with:
aws_assume_role: ${{ vars.AWS_ROLE_ARN }}
ssm_parameter_pairs: '/production/common/releasing/rubygems/api_key = GEM_HOST_API_KEY'

- id: build-and-test
name: Build and Test
uses: ./.github/actions/ci
with:
ruby-version: 3.0

- id: publish
name: Publish Package
uses: ./.github/actions/publish
with:
dry_run: ${{ inputs.dry_run }}

release-provenance:
needs: [ 'build-publish' ]
permissions:
actions: read
id-token: write
contents: write
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.7.0
with:
base64-subjects: "${{ needs.build-publish.outputs.gem-hash }}"
upload-assets: ${{ !inputs.dry_run }}
69 changes: 69 additions & 0 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: Run Release Please

on:
push:
branches:
- main

jobs:
release-package:
runs-on: ubuntu-latest
permissions:
id-token: write # Needed if using OIDC to get release secrets.
contents: write # Contents and pull-requests are for release-please to make releases.
pull-requests: write
outputs:
release-created: ${{ steps.release.outputs.release_created }}
upload-tag-name: ${{ steps.release.outputs.tag_name }}
gem-hash: ${{ steps.publish.outputs.gem-hash}}
steps:
- uses: google-github-actions/release-please-action@v3
id: release
with:
command: manifest
token: ${{secrets.GITHUB_TOKEN}}
default-branch: main

- uses: actions/checkout@v4
if: ${{ steps.release.outputs.releases_created }}
with:
fetch-depth: 0 # If you only need the current version keep this.

- uses: launchdarkly/gh-actions/actions/release-secrets@release-secrets-v1.0.0
if: ${{ steps.release.outputs.releases_created }}
name: 'Get rubygems API key'
with:
aws_assume_role: ${{ vars.AWS_ROLE_ARN }}
ssm_parameter_pairs: '/production/common/releasing/rubygems/api_key = GEM_HOST_API_KEY'

- uses: ./.github/actions/ci
if: ${{ steps.release.outputs.releases_created }}
with:
ruby-version: 3.0

- uses: ./.github/actions/build-docs
if: ${{ steps.release.outputs.releases_created }}

- uses: ./.github/actions/publish
id: publish
if: ${{ steps.release.outputs.releases_created }}
with:
dry_run: false

- uses: ./.github/actions/publish-docs
if: ${{ steps.release.outputs.releases_created }}
with:
token: ${{secrets.GITHUB_TOKEN}}

release-provenance:
needs: [ 'release-package' ]
if: ${{ needs.release-package.outputs.release-created }}
permissions:
actions: read
id-token: write
contents: write
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.7.0
with:
base64-subjects: "${{ needs.release-package.outputs.gem-hash }}"
upload-assets: true
upload-tag-name: ${{ needs.release-package.outputs.upload-tag-name }}
10 changes: 10 additions & 0 deletions .github/workflows/stale.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: 'Close stale issues and PRs'
on:
workflow_dispatch:
schedule:
# Happen once per day at 1:30 AM
- cron: '30 1 * * *'

jobs:
sdk-close-stale:
uses: launchdarkly/gh-actions/.github/workflows/sdk-stale.yml@main
3 changes: 3 additions & 0 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
".": "0.0.0"
}
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ gem "rubocop", "~> 1.21"
gem "rubocop-performance", "~> 1.15"
gem "rubocop-rake", "~> 0.6"
gem "rubocop-rspec", "~> 2.27"

# TODO: Take this out
gem 'launchdarkly-server-sdk', :git => 'https://github.com/launchdarkly/ruby-server-sdk', :branch => 'feat/hooks'
43 changes: 43 additions & 0 deletions PROVENANCE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
## Verifying SDK build provenance with the SLSA framework

LaunchDarkly uses the [SLSA framework](https://slsa.dev/spec/v1.0/about) (Supply-chain Levels for Software Artifacts) to help developers make their supply chain more secure by ensuring the authenticity and build integrity of our published SDK packages.

As part of [SLSA requirements for level 3 compliance](https://slsa.dev/spec/v1.0/requirements), LaunchDarkly publishes provenance about our SDK package builds using [GitHub's generic SLSA3 provenance generator](https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/generic/README.md#generation-of-slsa3-provenance-for-arbitrary-projects) for distribution alongside our packages. These attestations are available for download from the GitHub release page for the release version under Assets > `multiple-provenance.intoto.jsonl`.

To verify SLSA provenance attestations, we recommend using [slsa-verifier](https://github.com/slsa-framework/slsa-verifier). Example usage for verifying SDK packages is included below:

<!-- x-release-please-start-version -->
```
# Set the version of the SDK to verify
VERSION=0.0.0
```
<!-- x-release-please-end -->

```
# Download gem
$ gem fetch launchdarkly-server-sdk-otel -v $VERSION
# Download provenance from Github release
$ curl --location -O \
https://github.com/launchdarkly/ruby-server-sdk-otel/releases/download/${VERSION}/launchdarkly-server-sdk-otel-${VERSION}.gem.intoto.jsonl
# Run slsa-verifier to verify provenance against package artifacts
$ slsa-verifier verify-artifact \
--provenance-path launchdarkly-server-sdk-otel-${VERSION}.gem.intoto.jsonl \
--source-uri github.com/launchdarkly/ruby-server-sdk-otel \
launchdarkly-server-sdk-otel-${VERSION}.gem
```

Below is a sample of expected output.

```
Verified signature against tlog entry index 78214752 at URL: https://rekor.sigstore.dev/api/v1/log/entries/24296fb24b8ad77ab941c118ef7e0b2d656b962a0d670c6ac91cfa37d07b7b121ae560b00a978ecf
Verified build using builder "https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@refs/tags/v1.7.0" at commit f43b3ad834103fdc282652efbfe4963e8dfa737b
Verifying artifact launchdarkly-server-sdk-otel-0.0.0.gem: PASSED
PASSED: Verified SLSA provenance
```

Alternatively, to verify the provenance manually, the SLSA framework specifies [recommendations for verifying build artifacts](https://slsa.dev/spec/v1.0/verifying-artifacts) in their documentation.

**Note:** These instructions do not apply when building our libraries from source.
26 changes: 26 additions & 0 deletions docs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
ifeq ($(LD_RELEASE_VERSION),)
TITLE=LaunchDarkly Ruby OTEL Library
else
TITLE=LaunchDarkly Ruby OTEL Library ($(LD_RELEASE_VERSION))
endif

.PHONY: dependencies html

html: dependencies
rm -rf ./build
cd .. && yard doc \
-o docs/build/html \
--title "$(TITLE)" \
--no-private \
--markup markdown \
--embed-mixins \
-r docs/index.md \
lib/*.rb \
lib/**/*.rb \
lib/**/**/*.rb \
lib/**/**/**/*.rb
rm -f build/html/frames.html

dependencies:
gem install --conservative yard
gem install --conservative redcarpet # provides Markdown formatting
7 changes: 7 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# LaunchDarkly Server-side OTEL library for Ruby

This generated API documentation lists all types and methods in the SDK.

The API documentation for the most recent release is hosted on [GitHub Pages](https://launchdarkly.github.io/ruby-server-sdk-otel). API documentation for current and past releases is hosted on [RubyDoc.info](https://www.rubydoc.info/gems/launchdarkly-server-sdk-otel).

Source code and readme: [GitHub](https://github.com/launchdarkly/ruby-server-sdk-otel)

0 comments on commit abee0a6

Please sign in to comment.