diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index b587f2b..0000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -version: 2 -updates: - - package-ecosystem: bundler - directory: / - schedule: - interval: daily - open-pull-requests-limit: 10 diff --git a/.tailor b/.tailor deleted file mode 100644 index b7a1078..0000000 --- a/.tailor +++ /dev/null @@ -1,4 +0,0 @@ -Tailor.config do |config| - config.formatters "text" - config.file_set 'lib/**/*.rb' -end diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7ca5681..cc3b0c1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,14 +4,27 @@ Thanks for your interest in improving kitchen-cloudstack. Bug reports, feature r ## The most valuable contribution right now -The driver subclasses `Kitchen::Driver::SSHBase`, which was removed in Test -Kitchen 4.0. That means the driver cannot be used with a current Test Kitchen, -including the one bundled in Cinc Workstation and Chef Workstation, and users -have to pin `test-kitchen < 4.0`. - -Porting the driver onto the modern driver and transport API — as -[kitchen-rackspace](https://github.com/test-kitchen/kitchen-rackspace) did — -would be the single most useful change to this repository. +**Testing against a real CloudStack deployment.** The driver was rewritten onto +the modern Test Kitchen driver and transport API, and it is covered by unit +tests, but those tests stub the CloudStack API. Nobody has yet confirmed the +rewrite end to end against real hardware. + +The Windows and WinRM support is the least proven part. It works by setting the +transport to WinRM and letting the driver forward the transport's port and hand +over the password CloudStack generates, but it has not been run against a real +Windows template. If you have a CloudStack deployment, running `kitchen test` +against it — on Linux or Windows — and reporting what happened is genuinely the +most useful thing you can do for this project. + +Other changes that would be welcome: + +- Wrapping CloudStack and Excon errors in `Kitchen::ActionFailed`, so that bad + credentials produce a readable message rather than a `Fog::JSON::DecodeError` + and a stack trace. +- Making `create` idempotent, so that running it against an instance that + already exists in state does not deploy a second one. +- Looking up templates, service offerings, zones and networks by name rather + than requiring UUIDs in `kitchen.yml`. ## Reporting issues @@ -34,26 +47,45 @@ bundle install ## Tests and linting -Be aware of the current state of the tooling before you start: +Run the tests with: + +```sh +bundle exec rake +``` + +That runs RSpec, which is also the default Rake task. To run the linter: + +```sh +bundle exec cookstyle --chefstyle +``` + +CI runs both, plus `markdownlint` and `yamllint`, and runs the tests against +every Ruby from 3.1 to 4.0. All of it must pass before a pull request can merge. -- **There are no unit tests.** The repository contains no spec or test files, - so changes have to be verified manually against a real CloudStack deployment. -- **The Rakefile depends on unmaintained tools.** The default `rake` task runs - `cane`, `tailor`, and `countloc`. These are no longer maintained and do not - work on modern Ruby, so `bundle exec rake` is unlikely to succeed. -- **CI is out of date.** `.github/workflows/ci.yml` tests Ruby 2.5 to 3.0, all - of which are end of life, and its push trigger still refers to a `master` - branch that no longer exists. +### How the tests are organised -Adding unit tests and replacing the dead linters with -[Cookstyle](https://github.com/chef/cookstyle) would be very welcome, and can be -done independently of the `SSHBase` port described above. +Specs live under `spec/`: + +- `spec/kitchen/driver/cloudstack_spec.rb` covers the driver itself — what ends + up in instance state, how `create`, `destroy` and `status` behave, and how the + configured transport determines which port is forwarded. +- `spec/kitchen/driver/cloudstack/` covers each supporting class in isolation. + `ServerOptions` and `Credentials` are plain objects and are tested directly. +- `spec/integration/lifecycle_spec.rb` runs a full create/status/destroy cycle + through real Test Kitchen and real fog, stubbing only the HTTP layer, so + request signing, response parsing and plugin wiring are all exercised. + +Unit specs inject a fake client rather than stubbing `Fog::Compute` globally. +If you add behaviour that talks to CloudStack, prefer the same approach: it +keeps the tests fast and makes it obvious which API calls a change actually +makes. ## Manual testing against CloudStack -Until there are unit tests, any change needs to be exercised against a real -deployment. You will need API credentials, and a template, service offering, and -zone ID to deploy against. +Automated tests cannot prove a change works against a real deployment, so +anything that touches the CloudStack API is worth exercising for real. You will +need API credentials, and a template, service offering, and zone ID to deploy +against. Export the credentials rather than putting them in `kitchen.yml`: @@ -62,27 +94,27 @@ export CLOUDSTACK_API_KEY="..." export CLOUDSTACK_SECRET_KEY="..." ``` -Then run `kitchen test` against a pinned Test Kitchen. Afterwards, confirm in the -CloudStack UI that no VMs were left behind — a run that fails partway through can -leave one running. Setting `cloudstack_expunge: true` makes cleanup complete -rather than leaving VMs in the Destroyed state. +Then run `kitchen test`. Afterwards, confirm in the CloudStack UI that no VMs +were left behind — a run that fails partway through can leave one running. +Setting `cloudstack_expunge: true` makes cleanup complete rather than leaving +VMs in the Destroyed state. ## Submitting changes 1. Fork the repository. 2. Create a feature branch off `main`. -3. Make your change. -4. Describe how you verified it, since there are no automated tests to rely on. +3. Make your change, with tests covering it. +4. Run `bundle exec rake` and `bundle exec cookstyle --chefstyle`. 5. Push the branch to your fork and open a pull request. Please keep pull requests focused on a single change — it makes review much faster. Update the documentation in `README.md` when you add or change a -configuration option. +configuration option, and note user-visible changes in `CHANGELOG.md`. ## Release process -Releases are handled by the maintainers. - -1. Update `lib/kitchen/driver/cloudstack_version.rb` with the new version. -2. Update `CHANGELOG.md`. -3. Build and push the gem with `rake build` and `gem push`. +Releases are automated with +[release-please](https://github.com/googleapis/release-please). Merging to +`main` opens a release pull request that updates the version and changelog; +merging that pull request tags the release and publishes the gem to RubyGems +and GitHub Packages. diff --git a/kitchen-cloudstack.gemspec b/kitchen-cloudstack.gemspec index 89f0957..e14a9de 100644 --- a/kitchen-cloudstack.gemspec +++ b/kitchen-cloudstack.gemspec @@ -13,9 +13,17 @@ Gem::Specification.new do |spec| spec.homepage = "https://github.com/test-kitchen/kitchen-cloudstack" spec.license = "Apache-2.0" - spec.files = `git ls-files`.split($/) + spec.files = `git ls-files`.split($/).grep(/LICENSE|^lib/) spec.require_paths = ["lib"] + spec.metadata = { + "bug_tracker_uri" => "#{spec.homepage}/issues", + "changelog_uri" => "#{spec.homepage}/blob/main/CHANGELOG.md", + "documentation_uri" => "#{spec.homepage}/blob/main/README.md", + "source_code_uri" => spec.homepage, + "rubygems_mfa_required" => "true", + } + spec.add_dependency "test-kitchen", ">= 3.0", "< 5" spec.add_dependency "fog-cloudstack", "~> 0.1.0"