diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 348b4db..2e8c6dd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: permissions: contents: read id-token: write - runs-on: ${{ github.repository == 'stainless-sdks/dedalus-ruby' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} if: |- github.repository == 'stainless-sdks/dedalus-ruby' && (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata') @@ -56,7 +56,7 @@ jobs: lint: timeout-minutes: 10 name: lint - runs-on: ${{ github.repository == 'stainless-sdks/dedalus-ruby' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: @@ -73,7 +73,7 @@ jobs: test: timeout-minutes: 10 name: test - runs-on: ${{ github.repository == 'stainless-sdks/dedalus-ruby' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/publish-gem.yml b/.github/workflows/publish-gem.yml new file mode 100644 index 0000000..8807891 --- /dev/null +++ b/.github/workflows/publish-gem.yml @@ -0,0 +1,31 @@ +# This workflow is triggered when a GitHub release is created. +# It can also be run manually to re-publish to rubygems.org in case it failed for some reason. +# You can run this workflow by navigating to https://www.github.com/dedalus-labs/dedalus-ruby/actions/workflows/publish-gem.yml +name: Publish Gem +on: + workflow_dispatch: + + release: + types: [published] + +jobs: + publish: + name: publish + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: Set up Ruby + uses: ruby/setup-ruby@c4e5b1316158f92e3d49443a9d58b31d25ac0f8f # v1.306.0 + with: + bundler-cache: false + - run: |- + bundle install + + - name: Publish to RubyGems.org + run: | + bash ./bin/publish-gem + env: + # `RUBYGEMS_HOST` is only required for private gem repositories, not https://rubygems.org + RUBYGEMS_HOST: ${{ secrets.DEDALUS_RUBYGEMS_HOST || secrets.RUBYGEMS_HOST }} + GEM_HOST_API_KEY: ${{ secrets.DEDALUS_GEM_HOST_API_KEY || secrets.GEM_HOST_API_KEY }} diff --git a/.release-please-manifest.json b/.release-please-manifest.json new file mode 100644 index 0000000..3d2ac0b --- /dev/null +++ b/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "0.1.0" +} \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 3478eb5..dcb3502 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 32 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-8612890eae5e55f9236ad984991f4dc3712138acaa0005be3de43dabc6cd54d4.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-32ccb3c17674e0ee68fd6eafbdd0f210bccfd09fce0702e28b8278e06678deec.yml openapi_spec_hash: ccb02923079d91569a17162c88da590b -config_hash: 8b2f74aaf8a9b5a01242e7c23f721082 +config_hash: 3b16603a18779d453842a0d56638384d diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..12dbd29 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,22 @@ +# Changelog + +## 0.1.0 (2026-08-19) + +Full Changelog: [v0.0.1...v0.1.0](https://github.com/dedalus-labs/dedalus-ruby/compare/v0.0.1...v0.1.0) + +### Features + +* **stlc:** configurable CI runner and private-production-repo support in workflow templates ([aa8797c](https://github.com/dedalus-labs/dedalus-ruby/commit/aa8797c4cd9df4af4a413907ca8db82bdf87e787)) + + +### Bug Fixes + +* **client:** send content-type header for requests with an omitted optional body ([d50a2d4](https://github.com/dedalus-labs/dedalus-ruby/commit/d50a2d49e802d1b408dad1db6f363a189b70566f)) + + +### Chores + +* configure new SDK language ([9f8fd1e](https://github.com/dedalus-labs/dedalus-ruby/commit/9f8fd1e8883edce6a808ef697f350be22f1af5b2)) +* **internal:** allow the mock server port to be set with STAINLESS_MOCK_PORT ([df0ec2c](https://github.com/dedalus-labs/dedalus-ruby/commit/df0ec2c8751dbd78a197efeb31e6ef8c288f0a48)) +* **internal:** bound formatter parallelism to CPU count ([7dd40b9](https://github.com/dedalus-labs/dedalus-ruby/commit/7dd40b9359fa15428cc1c009875a76e1a67e74ba)) +* update SDK settings ([d5e3756](https://github.com/dedalus-labs/dedalus-ruby/commit/d5e3756283e2b3c690a66feb564a83908ff94348)) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c361e9b..cd5e40c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -43,13 +43,13 @@ If you’d like to use the repository from source, you can either install from g To install via git in your `Gemfile`: ```ruby -gem "dedalus", git: "https://github.com/stainless-sdks/dedalus-ruby" +gem "dedalus", git: "https://github.com/dedalus-labs/dedalus-ruby" ``` Alternatively, reference local copy of the repo: ```bash -$ git clone -- 'https://github.com/stainless-sdks/dedalus-ruby' '' +$ git clone -- 'https://github.com/dedalus-labs/dedalus-ruby' '' ``` ```ruby diff --git a/Gemfile.lock b/Gemfile.lock index ac84936..654614d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,7 +11,7 @@ GIT PATH remote: . specs: - dedalus (0.0.1) + dedalus (0.1.0) cgi connection_pool diff --git a/README.md b/README.md index 229c0d9..98f4c84 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Dedalus Ruby API library -The Dedalus Ruby library provides convenient access to the Dedalus REST API from any Ruby 3.2.0+ application. It ships with comprehensive types & docstrings in Yard, RBS, and RBI – [see below](https://github.com/stainless-sdks/dedalus-ruby#Sorbet) for usage with Sorbet. The standard library's `net/http` is used as the HTTP transport, with connection pooling via the `connection_pool` gem. +The Dedalus Ruby library provides convenient access to the Dedalus REST API from any Ruby 3.2.0+ application. It ships with comprehensive types & docstrings in Yard, RBS, and RBI – [see below](https://github.com/dedalus-labs/dedalus-ruby#Sorbet) for usage with Sorbet. The standard library's `net/http` is used as the HTTP transport, with connection pooling via the `connection_pool` gem. It is generated with [Stainless](https://www.stainless.com/). @@ -23,10 +23,14 @@ The REST API documentation can be found on [docs.dedaluslabs.ai](https://docs.de To use this gem, install via Bundler by adding the following to your application's `Gemfile`: + + ```ruby -gem "dedalus", "~> 0.0.1" +gem "dedalus", "~> 0.1.0" ``` + + ## Usage ```ruby @@ -279,4 +283,4 @@ Ruby 3.2.0 or higher. ## Contributing -See [the contributing documentation](https://github.com/stainless-sdks/dedalus-ruby/tree/main/CONTRIBUTING.md). +See [the contributing documentation](https://github.com/dedalus-labs/dedalus-ruby/tree/main/CONTRIBUTING.md). diff --git a/Rakefile b/Rakefile index c8d8921..6deb203 100644 --- a/Rakefile +++ b/Rakefile @@ -1,5 +1,6 @@ # frozen_string_literal: true +require "etc" require "pathname" require "securerandom" require "shellwords" @@ -37,7 +38,11 @@ multitask(:test) do ruby(*%w[-w -e], rb, verbose: false) { fail unless _1 } end -xargs = %w[xargs --no-run-if-empty --null --max-procs=0 --max-args=300 --] +# Cap parallelism at the CPU count. `--max-procs=0` spawns one process per +# 300-file batch with no upper bound; on large SDKs (thousands of files) that +# oversubscribes CPUs and stacks up rubocop processes, exhausting memory and +# slowing CI to the point of timing out. +xargs = %W[xargs --no-run-if-empty --null --max-procs=#{Etc.nprocessors} --max-args=300 --] ruby_opt = {"RUBYOPT" => [ENV["RUBYOPT"], "--encoding=UTF-8"].compact.join(" ")} filtered = ->(ext, dirs) do diff --git a/dedalus.gemspec b/dedalus.gemspec index f6a300c..3d2d77b 100644 --- a/dedalus.gemspec +++ b/dedalus.gemspec @@ -10,7 +10,7 @@ Gem::Specification.new do |s| s.email = "oss@dedaluslabs.ai" s.homepage = "https://gemdocs.org/gems/dedalus" s.metadata["homepage_uri"] = s.homepage - s.metadata["source_code_uri"] = "https://github.com/stainless-sdks/dedalus-ruby" + s.metadata["source_code_uri"] = "https://github.com/dedalus-labs/dedalus-ruby" s.metadata["rubygems_mfa_required"] = false.to_s s.required_ruby_version = ">= 3.2.0" diff --git a/lib/dedalus/internal/transport/base_client.rb b/lib/dedalus/internal/transport/base_client.rb index 7c55326..b441ddb 100644 --- a/lib/dedalus/internal/transport/base_client.rb +++ b/lib/dedalus/internal/transport/base_client.rb @@ -306,7 +306,10 @@ def initialize( Dedalus::Internal::Util.deep_merge(*[req[:body], opts[:extra_body]].compact) end - headers.delete("content-type") if body.nil? + # Generated methods always pass `req[:body]` for operations that define a + # request body, so only elide the content-type header when the operation + # has no body at all, not when an optional body param was omitted. + headers.delete("content-type") if body.nil? && !req.key?(:body) url = Dedalus::Internal::Util.join_parsed_uri( @base_url_components, diff --git a/lib/dedalus/version.rb b/lib/dedalus/version.rb index 2602aa7..8814ee8 100644 --- a/lib/dedalus/version.rb +++ b/lib/dedalus/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Dedalus - VERSION = "0.0.1" + VERSION = "0.1.0" end diff --git a/release-please-config.json b/release-please-config.json new file mode 100644 index 0000000..ab969e5 --- /dev/null +++ b/release-please-config.json @@ -0,0 +1,73 @@ +{ + "packages": { + ".": {} + }, + "$schema": "https://raw.githubusercontent.com/stainless-api/release-please/main/schemas/config.json", + "include-v-in-tag": true, + "include-component-in-tag": false, + "versioning": "prerelease", + "prerelease": true, + "bump-minor-pre-major": true, + "bump-patch-for-minor-pre-major": false, + "pull-request-header": "Automated Release PR", + "pull-request-title-pattern": "release: ${version}", + "changelog-sections": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "perf", + "section": "Performance Improvements" + }, + { + "type": "revert", + "section": "Reverts" + }, + { + "type": "chore", + "section": "Chores" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "style", + "section": "Styles" + }, + { + "type": "refactor", + "section": "Refactors" + }, + { + "type": "test", + "section": "Tests", + "hidden": true + }, + { + "type": "build", + "section": "Build System" + }, + { + "type": "ci", + "section": "Continuous Integration", + "hidden": true + } + ], + "reviewers": [ + "@windsornguyen" + ], + "release-type": "ruby", + "version-file": "lib/dedalus/version.rb", + "extra-files": [ + { + "type": "ruby-readme", + "path": "README.md" + } + ] +} \ No newline at end of file diff --git a/scripts/mock b/scripts/mock index 9c7c439..6376077 100755 --- a/scripts/mock +++ b/scripts/mock @@ -4,6 +4,11 @@ set -e cd "$(dirname "$0")/.." +if [ "$1" == "--install" ]; then + npm exec --package=@stdy/cli@0.22.1 -- steady --version + exit 0 +fi + if [[ -n "$1" && "$1" != '--'* ]]; then URL="$1" shift @@ -20,16 +25,18 @@ fi echo "==> Starting mock server with URL ${URL}" # Run steady mock on the given spec +MOCK_PORT="${STAINLESS_MOCK_PORT:-4010}" + if [ "$1" == "--daemon" ]; then # Pre-install the package so the download doesn't eat into the startup timeout npm exec --package=@stdy/cli@0.22.1 -- steady --version - npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=repeat --validator-form-array-format=repeat --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" &> .stdy.log & + npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p "$MOCK_PORT" --validator-query-array-format=repeat --validator-form-array-format=repeat --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" &> .stdy.log & # Wait for server to come online via health endpoint (max 30s) echo -n "Waiting for server" attempts=0 - while ! curl --silent --fail "http://127.0.0.1:4010/_x-steady/health" >/dev/null 2>&1; do + while ! curl --silent --fail "http://127.0.0.1:$MOCK_PORT/_x-steady/health" >/dev/null 2>&1; do if ! kill -0 $! 2>/dev/null; then echo cat .stdy.log @@ -48,5 +55,5 @@ if [ "$1" == "--daemon" ]; then echo else - npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=repeat --validator-form-array-format=repeat --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" + npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p "$MOCK_PORT" --validator-query-array-format=repeat --validator-form-array-format=repeat --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" fi diff --git a/scripts/test b/scripts/test index 5470f81..0c409fb 100755 --- a/scripts/test +++ b/scripts/test @@ -9,8 +9,10 @@ GREEN='\033[0;32m' YELLOW='\033[0;33m' NC='\033[0m' # No Color +MOCK_PORT="${STAINLESS_MOCK_PORT:-4010}" + function steady_is_running() { - curl --silent "http://127.0.0.1:4010/_x-steady/health" >/dev/null 2>&1 + curl --silent "http://127.0.0.1:$MOCK_PORT/_x-steady/health" >/dev/null 2>&1 } kill_server_on_port() { @@ -27,7 +29,7 @@ function is_overriding_api_base_url() { if ! is_overriding_api_base_url && ! steady_is_running ; then # When we exit this script, make sure to kill the background mock server process - trap 'kill_server_on_port 4010' EXIT + trap 'kill_server_on_port "$MOCK_PORT"' EXIT # Start the dev server ./scripts/mock --daemon @@ -43,7 +45,7 @@ elif ! steady_is_running ; then echo -e "To run the server, pass in the path or url of your OpenAPI" echo -e "spec to the steady command:" echo - echo -e " \$ ${YELLOW}npm exec --package=@stdy/cli@0.22.1 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p 4010 --validator-query-array-format=repeat --validator-form-array-format=repeat --validator-query-object-format=brackets --validator-form-object-format=brackets${NC}" + echo -e " \$ ${YELLOW}npm exec --package=@stdy/cli@0.22.1 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p $MOCK_PORT --validator-query-array-format=repeat --validator-form-array-format=repeat --validator-query-object-format=brackets --validator-form-object-format=brackets${NC}" echo exit 1 @@ -52,5 +54,9 @@ else echo fi +if [ -n "${STAINLESS_MOCK_PORT:-}" ] && ! is_overriding_api_base_url ; then + export TEST_API_BASE_URL="http://127.0.0.1:$MOCK_PORT" +fi + echo "==> Running tests" bundle exec rake test "$@"