diff --git a/.github/actions/ci/action.yml b/.github/actions/check/action.yml similarity index 58% rename from .github/actions/ci/action.yml rename to .github/actions/check/action.yml index 2b3e6193..3d5030fd 100644 --- a/.github/actions/ci/action.yml +++ b/.github/actions/check/action.yml @@ -1,9 +1,10 @@ -name: CI Workflow -description: 'Shared CI workflow.' +name: Quality control checks +description: 'Runs tests, linters, and contract tests' inputs: - ruby-version: - description: 'The version of ruby to setup and run' - required: true + flaky: + description: 'Is the platform under test considered flaky?' + required: false + default: 'false' token: description: 'GH token used to fetch the SDK test harness' required: true @@ -11,17 +12,8 @@ inputs: runs: using: composite steps: - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ inputs.ruby-version }} - bundler: 2.2.33 - - - name: Install dependencies - shell: bash - run: bundle _2.2.33_ install - - name: Skip flaky tests for jruby - if: ${{ startsWith(inputs.ruby-version, 'jruby') }} + if: ${{ inputs.flaky == 'true' }} shell: bash run: echo "SPEC_TAGS=-t '~flaky'" >> $GITHUB_ENV @@ -34,17 +26,17 @@ runs: run: bundle exec rubocop --parallel - name: Build contract tests - if: ${{ !startsWith(inputs.ruby-version, 'jruby') }} + if: ${{ inputs.flaky != 'true' }} shell: bash run: make build-contract-tests - name: Start contract test service - if: ${{ !startsWith(inputs.ruby-version, 'jruby') }} + if: ${{ inputs.flaky != 'true' }} shell: bash run: make start-contract-test-service-bg - uses: launchdarkly/gh-actions/actions/contract-tests@contract-tests-v1.2.0 - if: ${{ !startsWith(inputs.ruby-version, 'jruby') }} + if: ${{ inputs.flaky != 'true' }} with: test_service_port: 9000 enable_persistence_tests: true diff --git a/.github/actions/publish-docs/action.yml b/.github/actions/publish-docs/action.yml index 0a827c03..4a6fb9ae 100644 --- a/.github/actions/publish-docs/action.yml +++ b/.github/actions/publish-docs/action.yml @@ -12,4 +12,4 @@ runs: 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< + github_token: ${{ inputs.token }} # For the shared action the token should be a GITHUB_TOKEN< diff --git a/.github/actions/publish/action.yml b/.github/actions/publish/action.yml index 691de8a7..d775e2fb 100644 --- a/.github/actions/publish/action.yml +++ b/.github/actions/publish/action.yml @@ -12,13 +12,13 @@ outputs: runs: using: composite steps: - - name: Build gemspec - shell: bash - run: gem build launchdarkly-server-sdk.gemspec + - uses: actions/download-artifact@v4 + with: + pattern: 'gems-*' - name: Hash gem for provenance id: gem-hash - shell: bash + shell: bash run: | echo "gem-hash=$(sha256sum launchdarkly-server-sdk-*.gem | base64 -w0)" >> "$GITHUB_OUTPUT" diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml new file mode 100644 index 00000000..8ecb07e1 --- /dev/null +++ b/.github/actions/setup/action.yml @@ -0,0 +1,23 @@ +name: Setup Ruby +description: 'Install ruby, and optionally the project dependencies' +inputs: + version: + description: 'The version of ruby to setup and run' + required: true + install-dependencies: + description: 'Whether to install the project dependencies' + required: false + default: 'true' + +runs: + using: composite + steps: + - uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ inputs.version }} + bundler: 2.2.33 + + - name: Install dependencies + if: ${{ inputs.install-dependencies == 'true' }} + shell: bash + run: bundle _2.2.33_ install diff --git a/.github/workflows/build-gem.yml b/.github/workflows/build-gem.yml new file mode 100644 index 00000000..c9f3b0c1 --- /dev/null +++ b/.github/workflows/build-gem.yml @@ -0,0 +1,58 @@ +name: Build gem + +on: + workflow_call: + inputs: + version: + description: 'The version of ruby to build against' + type: string + default: '3.0' + upload-artifact: + description: 'Whether to upload the gem as an artifact' + type: boolean + required: false + default: true + +jobs: + build-gem: + runs-on: ubuntu-latest + + env: + LD_SKIP_DATABASE_TESTS: 0 + BUILD_PLATFORM: ${{ startsWith(inputs.version, 'jruby') && 'jruby' || 'ruby' }} + FLAKY: ${{ startsWith(inputs.version, 'jruby') && 'true' || 'false' }} + + services: + redis: + image: redis + ports: + - 6379:6379 + dynamodb: + image: amazon/dynamodb-local + ports: + - 8000:8000 + consul: + image: hashicorp/consul + ports: + - 8500:8500 + + steps: + - uses: actions/checkout@v4 + + - uses: ./.github/actions/setup + with: + version: ${{ inputs.version }} + + - uses: ./.github/actions/check + with: + flaky: ${{ env.FLAKY }} + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Build gemspec + run: gem build launchdarkly-server-sdk.gemspec --platform=$BUILD_PLATFORM + + - uses: actions/upload-artifact@v4 + if: ${{ inputs.upload-artifact }} + with: + name: gems-${{ inputs.version }} + path: launchdarkly-server-sdk-*.gem diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 24230501..e63c057c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,47 +10,32 @@ on: - '**.md' jobs: - build-linux: + build-linux-oldest: + uses: ./.github/workflows/build-gem.yml + with: + version: '3.0' + + build-linux-latest: + uses: ./.github/workflows/build-gem.yml + with: + version: '3.2' + + build-linux-jruby: + uses: ./.github/workflows/build-gem.yml + with: + version: 'jruby-9.4' + + build-docs: runs-on: ubuntu-latest - env: - LD_SKIP_DATABASE_TESTS: 0 - - strategy: - fail-fast: false - matrix: - ruby-version: - - '3.0' - - '3.1' - - '3.2' - - jruby-9.4 - - services: - redis: - image: redis - ports: - - 6379:6379 - dynamodb: - image: amazon/dynamodb-local - ports: - - 8000:8000 - consul: - image: hashicorp/consul - ports: - - 8500:8500 - steps: - uses: actions/checkout@v4 - with: - fetch-depth: 0 # If you only need the current version keep this. - - uses: ./.github/actions/ci + - uses: ./.github/actions/setup with: - ruby-version: ${{ matrix.ruby-version }} - token: ${{ secrets.GITHUB_TOKEN }} + version: '3.0' - uses: ./.github/actions/build-docs - if: ${{ !startsWith(matrix.ruby-version, 'jruby') }} build-windows: runs-on: windows-latest @@ -65,13 +50,9 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: ruby/setup-ruby@v1 + - uses: ./.github/actions/setup with: - ruby-version: 3.0 - bundler: 2.2.33 - - - name: Install dependencies - run: bundle _2.2.33_ install + version: '3.0' - name: Run tests run: bundle _2.2.33_ exec rspec spec diff --git a/.github/workflows/manual-publish-docs.yml b/.github/workflows/manual-publish-docs.yml index f883d290..be3859b7 100644 --- a/.github/workflows/manual-publish-docs.yml +++ b/.github/workflows/manual-publish-docs.yml @@ -5,19 +5,20 @@ 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 + - uses: ./.github/actions/setup with: - ruby-version: 3.0 - bundler: 2.2.33 + version: '3.0' + install-dependencies: false - uses: ./.github/actions/build-docs - uses: ./.github/actions/publish-docs with: - token: ${{secrets.GITHUB_TOKEN}} + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/manual-publish.yml b/.github/workflows/manual-publish.yml index c8d5f83b..f033bb9f 100644 --- a/.github/workflows/manual-publish.yml +++ b/.github/workflows/manual-publish.yml @@ -8,16 +8,32 @@ on: required: true jobs: - build-publish: + build-ruby-gem: + uses: ./.github/workflows/build-gem.yml + with: + version: '3.0' + + build-jruby-gem: + uses: ./.github/workflows/build-gem.yml + with: + version: 'jruby-9.4' + + publish: runs-on: ubuntu-latest - # Needed to get tokens during publishing. - permissions: - id-token: write - contents: read + needs: [ 'build-ruby-gem', 'build-jruby-gem' ] + outputs: - gem-hash: ${{ steps.publish.outputs.gem-hash}} + gem-hash: ${{ steps.publish.outputs.gem-hash }} + + permissions: + id-token: write # Needed if using OIDC to get release secrets. + contents: write + steps: - - uses: actions/checkout@v4 + - uses: ./.github/actions/setup + with: + version: '3.0' + install-dependencies: false - uses: launchdarkly/gh-actions/actions/release-secrets@release-secrets-v1.2.0 name: 'Get rubygems API key' @@ -25,26 +41,27 @@ jobs: 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 - token: ${{ secrets.GITHUB_TOKEN }} + - uses: ./.github/actions/build-docs - - id: publish - name: Publish Package - uses: ./.github/actions/publish + - uses: ./.github/actions/publish + id: publish with: dry_run: ${{ inputs.dry_run }} + - uses: ./.github/actions/publish-docs + if: ${{ !inputs.dry_run }} + with: + token: ${{secrets.GITHUB_TOKEN}} + release-provenance: - needs: [ 'build-publish' ] + needs: [ 'publish' ] + permissions: actions: read id-token: write contents: write + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0 with: - base64-subjects: "${{ needs.build-publish.outputs.gem-hash }}" + base64-subjects: "${{ needs.publish.outputs.gem-hash }}" upload-assets: ${{ !inputs.dry_run }} diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 0abdbe62..4411780f 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -8,59 +8,79 @@ on: 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: googleapis/release-please-action@v4 id: release - - uses: actions/checkout@v4 - if: ${{ steps.release.outputs.releases_created == 'true' }} + build-ruby-gem: + needs: [ 'release-package' ] + if: ${{ needs.release-package.outputs.release-created == 'true' }} + uses: ./.github/workflows/build-gem.yml + with: + platform: 'ruby' + + build-jruby-gem: + needs: [ 'release-package' ] + if: ${{ needs.release-package.outputs.release-created == 'true' }} + uses: ./.github/workflows/build-gem.yml + with: + platform: 'jruby' + + publish: + runs-on: ubuntu-latest + needs: [ 'release-package', 'build-ruby-gem', 'build-jruby-gem' ] + if: ${{ needs.release-package.outputs.release-created == 'true' }} + + outputs: + gem-hash: ${{ steps.publish.outputs.gem-hash }} + + 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. + + steps: + - uses: ./.github/actions/setup with: - fetch-depth: 0 # If you only need the current version keep this. + version: '3.0' + install-dependencies: false - uses: launchdarkly/gh-actions/actions/release-secrets@release-secrets-v1.2.0 - if: ${{ steps.release.outputs.releases_created == 'true' }} 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 == 'true' }} - with: - ruby-version: 3.0 - token: ${{ secrets.GITHUB_TOKEN }} - - uses: ./.github/actions/build-docs - if: ${{ steps.release.outputs.releases_created == 'true' }} - uses: ./.github/actions/publish id: publish - if: ${{ steps.release.outputs.releases_created == 'true' }} with: dry_run: false - uses: ./.github/actions/publish-docs - if: ${{ steps.release.outputs.releases_created == 'true' }} with: - token: ${{secrets.GITHUB_TOKEN}} + token: ${{ secrets.GITHUB_TOKEN }} release-provenance: - needs: [ 'release-package' ] + needs: [ 'release-package', 'publish' ] if: ${{ needs.release-package.outputs.release-created == 'true' }} + permissions: actions: read id-token: write contents: write + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0 with: - base64-subjects: "${{ needs.release-package.outputs.gem-hash }}" + base64-subjects: "${{ needs.publish.outputs.gem-hash }}" upload-assets: true upload-tag-name: ${{ needs.release-package.outputs.upload-tag-name }}