diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 32ab53ba..0c2f0746 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,12 +55,11 @@ jobs: - name: Install dependencies shell: bash run: | - gem install --no-document toys bundle install - name: Test ${{ matrix.task }} shell: bash # zizmor: ignore[template-injection] run: | for task in $(echo "${{ matrix.task }}" | tr ',' ' '); do - toys "$task" < /dev/null + bundle exec rake "$task" < /dev/null done diff --git a/.kokoro/samples.sh b/.kokoro/samples.sh index 50ae3929..8308a24f 100755 --- a/.kokoro/samples.sh +++ b/.kokoro/samples.sh @@ -7,8 +7,6 @@ set -eo pipefail export GEM_HOME=$HOME/.gem export PATH=$GEM_HOME/bin:$PATH -gem install --no-document toys - # To run acceptance tests for samples, we need the `sample_loader.rb` helper # from the `googleapis/ruby-common-tools` repository. # @@ -23,4 +21,5 @@ gem install --no-document toys # step explicit and reliable. curl -sSL https://raw.githubusercontent.com/googleapis/ruby-common-tools/main/lib/sample_loader.rb -o samples/acceptance/sample_loader.rb -toys samples < /dev/null +bundle install +bundle exec rake samples < /dev/null diff --git a/.toys/.lib/repo_context.rb b/.toys/.lib/repo_context.rb deleted file mode 100644 index bde035e6..00000000 --- a/.toys/.lib/repo_context.rb +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright 2022 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -class RepoContext - @loaded_env = false - - def self.load_kokoro_env - return if @loaded_env - @loaded_env = true - - gfile_dir = ::ENV["KOKORO_GFILE_DIR"] - return unless gfile_dir - - filename = "#{gfile_dir}/ruby_env_vars.json" - raise "#{filename} is not a file" unless ::File.file? filename - env_vars = ::JSON.parse ::File.read filename - env_vars.each { |k, v| ::ENV[k] ||= v } - - filename = "#{gfile_dir}/secret_manager/ruby-main-ci-service-account" - raise "#{filename} is not a file" unless ::File.file? filename - ::ENV["GOOGLE_APPLICATION_CREDENTIALS"] = filename - - # Extract project_id from the key file if available - require "json" - key_data = JSON.parse File.read filename - if key_data["project_id"] - puts "Inferred project_id from keyfile: #{key_data['project_id']}" - ::ENV["GOOGLE_CLOUD_PROJECT"] ||= key_data["project_id"] - end - end -end diff --git a/.toys/.toys.rb b/.toys/.toys.rb deleted file mode 100644 index 9f76ff2a..00000000 --- a/.toys/.toys.rb +++ /dev/null @@ -1,56 +0,0 @@ -# frozen_string_literal: true - -# Copyright 2021 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -expand :clean, paths: :gitignore - -tool "spec" do - desc "Run RSpec tests" - include :exec - def run - exec ["bundle", "exec", "rspec"] - end -end - -tool "test" do - desc "Run unit tests" - include :exec - def run - exec ["bundle", "exec", "ruby", "-Ilib", "-Itest", "-e", "Dir.glob('test/**/*_test.rb').each{|f| require File.expand_path(f)}"] - end -end - -tool "integration" do - desc "Run integration tests" - include :exec - def run - exec ["bundle", "exec", "ruby", "-Ilib", "-Iintegration", "-e", "Dir.glob('integration/**/*_test.rb').each{|f| require File.expand_path(f)}"] - end -end - -expand :rubocop, bundler: true - -tool "yardoc" do - desc "Generate documentation" - include :exec - def run - exec ["bundle", "exec", "yard", "doc"] - end -end -alias_tool :yard, :yardoc - -expand :gem_build - -expand :gem_build, name: "install", install_gem: true diff --git a/.toys/ci.rb b/.toys/ci.rb deleted file mode 100644 index 2f7263fa..00000000 --- a/.toys/ci.rb +++ /dev/null @@ -1,45 +0,0 @@ -# frozen_string_literal: true - -# Copyright 2021 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -desc "Run CI checks" - -TESTS = ["test", "integration", "spec", "rubocop", "yardoc", "build", "linkinator"] - -flag :only -TESTS.each do |name| - flag "include_#{name}".to_sym, "--[no-]include-#{name}" -end - -include :exec, result_callback: :handle_result -include :terminal - -def handle_result result - if result.success? - puts "** #{result.name} passed\n\n", :green, :bold - else - puts "** CI terminated: #{result.name} failed!", :red, :bold - exit 1 - end -end - -def run - ::Dir.chdir context_directory - TESTS.each do |name| - setting = get "include_#{name}".to_sym - setting = !only if setting.nil? - exec ["toys", name], name: name.capitalize if setting - end -end diff --git a/.toys/linkinator.rb b/.toys/linkinator.rb deleted file mode 100644 index 66b06c0c..00000000 --- a/.toys/linkinator.rb +++ /dev/null @@ -1,45 +0,0 @@ -# frozen_string_literal: true - -# Copyright 2021 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -desc "Run Link checks" - -flag :install, desc: "Install linkinator instead of running checks" - -include :exec, e: true -include :terminal - -def run - ::Dir.chdir context_directory - if install - Kernel.exec "npm install linkinator" - else - exec_tool ["yardoc"] - check_links - end -end - -def check_links - result = exec ["npx", "linkinator", "./doc", "--skip", "stackoverflow.com"], out: :capture - puts result.captured_out - checked_links = result.captured_out.split "\n" - checked_links.select! { |link| link =~ /^\[(\d+)\]/ && ::Regexp.last_match[1] != "200" } - unless checked_links.empty? - checked_links.each do |link| - puts link, :yellow - end - exit 1 - end -end diff --git a/.toys/samples.rb b/.toys/samples.rb deleted file mode 100644 index bb0fa013..00000000 --- a/.toys/samples.rb +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2022 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -desc "Run samples tests" - -include :exec -include :terminal, styled: true - -def run - require "json" - require "repo_context" - RepoContext.load_kokoro_env - - Dir.chdir File.join(context_directory, "samples") do - puts "Updating samples bundle ...", :bold, :cyan - exec ["bundle", "install"] - - puts "Samples tests ...", :bold, :cyan - cmd = ["bundle", "exec", "ruby", "-I../lib", "-Iacceptance", "-e", - "Dir.glob('acceptance/*_test.rb').each{|f| require File.expand_path(f)}"] - - exec cmd - end -end diff --git a/Gemfile b/Gemfile index 55c2f03f..10249ba4 100755 --- a/Gemfile +++ b/Gemfile @@ -14,6 +14,7 @@ gem "minitest", "~> 5.14" gem "minitest-focus", "~> 1.1" gem "pstore", "~> 0.2.1" gem "rack-test", "~> 2.0" +gem "rake", "~> 13.0" gem "redcarpet", "~> 3.0" gem "redis", ">= 4.0", "< 6" gem "rspec", "~> 3.0" diff --git a/Gemfile.lock b/Gemfile.lock index efa72b6a..5e47ca72 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - googleauth (1.17.3) + googleauth (1.17.4) faraday (>= 1.0, < 3.a) google-cloud-env (~> 2.2) google-logging-utils (~> 0.1) @@ -79,6 +79,7 @@ GEM rack-test (2.2.0) rack (>= 1.3) rainbow (3.1.1) + rake (13.4.2) rbs (4.1.1) logger prism (>= 1.6.0) @@ -156,6 +157,7 @@ DEPENDENCIES minitest-focus (~> 1.1) pstore (~> 0.2.1) rack-test (~> 2.0) + rake (~> 13.0) redcarpet (~> 3.0) redis (>= 4.0, < 6) rspec (~> 3.0) @@ -181,7 +183,7 @@ CHECKSUMS google-cloud-env (2.4.0) sha256=01cb35ecee5d1c4d1cd4deaed8bb5bddc838e296bcc2a35c5d1ddd07ce40d28d google-logging-utils (0.2.0) sha256=675462b4ea5affa825a3442694ca2d75d0069455a1d0956127207498fca3df7b google-style (1.32.0) sha256=3b13068979e5b8caa067ecce9bf818b6cf0e5eb706ead41c5b905f237d9bfb01 - googleauth (1.17.3) + googleauth (1.17.4) hashdiff (1.2.1) sha256=9c079dbc513dfc8833ab59c0c2d8f230fa28499cc5efb4b8dd276cf931457cd1 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 @@ -208,6 +210,7 @@ CHECKSUMS rack (3.2.6) sha256=5ed78e1f73b2e25679bec7d45ee2d4483cc4146eb1be0264fc4d94cb5ef212c2 rack-test (2.2.0) sha256=005a36692c306ac0b4a9350355ee080fd09ddef1148a5f8b2ac636c720f5c463 rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a + rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701 rbs (4.1.1) sha256=1bf118f2f95d1cd3956357645d495152b661e0257e57781d18ceecd461622b9e rdoc (8.0.0) sha256=03bf8c08a9639658855a0cfd77c0abca8325c227693f7f33f82957811348c469 redcarpet (3.6.1) sha256=d444910e6aa55480c6bcdc0cdb057626e8a32c054c29e793fa642ba2f155f445 diff --git a/Rakefile b/Rakefile new file mode 100644 index 00000000..4fd43236 --- /dev/null +++ b/Rakefile @@ -0,0 +1,101 @@ +# frozen_string_literal: true + +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require "bundler/gem_tasks" +require "json" +require "open3" +require "rake/clean" +require "rake/testtask" +require "rspec/core/rake_task" +require "rubocop/rake_task" +require "yard" + +# The entries in .gitignore. rake/clean already removes "**/*~". +CLEAN.include "**/*.gem", "**/*.rbc", ".config", "coverage", "InstalledFiles", "pkg", "spec/reports", "test/tmp", + "test/version_tmp", "tmp", "**/.dat*", "**/.repl_history", "build", ".yardoc", "_yardoc", "doc", + "rdoc", ".bundle", "lib/bundler/man", "**/.rvmrc", "node_modules", "package-lock.json" + +RSpec::Core::RakeTask.new :spec + +Rake::TestTask.new :test do |t| + t.libs = ["lib", "test"] + t.test_files = FileList["test/**/*_test.rb"] + t.warning = false +end + +Rake::TestTask.new :integration do |t| + t.libs = ["lib", "integration"] + t.test_files = FileList["integration/**/*_test.rb"] + t.warning = false +end + +RuboCop::RakeTask.new + +YARD::Rake::YardocTask.new :yardoc + +desc "Alias for yardoc, used by the release tooling" +task yard: :yardoc + +desc "Check the links in the generated documentation" +task linkinator: :yardoc do + output, status = Open3.capture2 "npx", "linkinator", "./doc", "--skip", "stackoverflow.com" + puts output + broken = output.lines.select { |line| line =~ /^\[(\d+)\]/ && Regexp.last_match(1) != "200" } + broken.each { |line| puts line } + abort "linkinator failed" unless status.success? && broken.empty? +end + +namespace :linkinator do + desc "Install linkinator" + task :install do + sh "npm", "install", "linkinator" + end +end + +# On Kokoro, load the shared environment variables and the CI service account. +def load_kokoro_env + gfile_dir = ENV["KOKORO_GFILE_DIR"] + return unless gfile_dir + + filename = "#{gfile_dir}/ruby_env_vars.json" + raise "#{filename} is not a file" unless File.file? filename + JSON.parse(File.read(filename)).each { |k, v| ENV[k] ||= v } + + filename = "#{gfile_dir}/secret_manager/ruby-main-ci-service-account" + raise "#{filename} is not a file" unless File.file? filename + ENV["GOOGLE_APPLICATION_CREDENTIALS"] = filename + + project_id = JSON.parse(File.read(filename))["project_id"] + return unless project_id + puts "Inferred project_id from keyfile: #{project_id}" + ENV["GOOGLE_CLOUD_PROJECT"] ||= project_id +end + +desc "Run samples tests" +task :samples do + # The samples have their own Gemfile, so leave the root bundle first. + Bundler.with_unbundled_env do + load_kokoro_env + puts "Updating samples bundle ..." + sh "bundle", "install", chdir: "samples" + puts "Samples tests ..." + sh "bundle", "exec", "ruby", "-I../lib", "-Iacceptance", "-e", + "Dir.glob('acceptance/*_test.rb').each{|f| require File.expand_path(f)}", chdir: "samples" + end +end + +desc "Run CI checks" +task ci: ["test", "integration", "spec", "rubocop", "yardoc", "build", "linkinator"]