crawlscope 0.8.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 89be661c49b5f2148a9d7962d81d522eedaedbba89c1f9dcf8474d62cfffd5f2
4
- data.tar.gz: d27a26792cc5cfdab191371c3d005cf43298b02896cb7cbdf2113a5f341e6c12
3
+ metadata.gz: 94c540760a23969d9abd10c27866c6c14a7caf520a261e2f6a213ffabe5440de
4
+ data.tar.gz: f1caacfe42dc2e4cb398d1732b1a265761c0aabffc951647a93972479501835d
5
5
  SHA512:
6
- metadata.gz: 5c90219d9430a09a3c95c5cb6367817cbc996f4ba69857781ddf6d2050373c9bfef2ad3de545a328542fa7362494df05be85cfa2c5e11f359b84870c8bee2ea6
7
- data.tar.gz: 632ddff7f77d1c0eb62e6f9db0c9a36f8c3c080d2ac3b6b93bc03fcea65453d916ecbf7b39eb34e9b16d750309e7814586e2a84b4cd0157609a47402bcccf8ef
6
+ metadata.gz: e24e81f82b40938cb48182aef3657b3d49a273269900a5d47edeccd35f34081293044b1f9e0fb7e5bd6fbad26d18b0ec0f897b21b2935031d0601b081f1c0f2b
7
+ data.tar.gz: af73839632a975bc34145dbb821a02d953175cd5d6fa7c0af419ba7f488e02d043a946aeea8c338de1e338bc6864744a3a6ac23bbcaed6fa3ecf708ff2a4005c
data/CHANGELOG.md CHANGED
@@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.9.0] - 2026-11-04
9
+
10
+ ### Changed
11
+
12
+ - Require Ruby 4.0 or newer.
13
+ - Use published Gemkit 0.1.0 for shared verification and release PRs, with workflow callers pinned to the same release commit.
14
+
15
+ ### Added
16
+
17
+ - Support optional host-installed Rails 8 (`>= 8.0`, `< 9`), including explicit `crawlscope/rails` loading after the core.
18
+ - Reuse all packaged audit tasks in the repository, including indexability and content-quality checks.
19
+
20
+ ### Removed
21
+
22
+ - Remove Railties as a runtime dependency so the Ruby library and CLI work without Rails.
23
+ - Replace local tagging and hook bypasses with reviewed release PRs published by GitHub Actions.
24
+
8
25
  ## [0.8.1] - 2026-10-06
9
26
 
10
27
 
data/README.md CHANGED
@@ -32,7 +32,8 @@ The default rule set includes:
32
32
 
33
33
  ## Installation
34
34
 
35
- Crawlscope requires Ruby 3.3 or newer.
35
+ Crawlscope requires Ruby 4.0 or newer. Rails is optional; the CLI and Ruby
36
+ library run without it. Rails integration requires host-installed Rails 8.
36
37
 
37
38
  Add this line to your application's Gemfile:
38
39
 
@@ -222,6 +223,10 @@ metric names and reports each metric independently.
222
223
 
223
224
  ## Rails Usage
224
225
 
226
+ Install Rails 8 in the host application; Crawlscope does not install Railties.
227
+ For a process that loads Crawlscope before Rails, require `crawlscope/rails`
228
+ after Rails is available. The Ruby and CLI entry points remain independent of Rails.
229
+
225
230
  Run the install generator after adding the gem:
226
231
 
227
232
  ```bash
@@ -432,68 +437,92 @@ That makes `crawlscope` useful as the audit engine while the app remains the own
432
437
 
433
438
  ## Development
434
439
 
435
- ```bash
440
+ Shared development tooling comes from published `ethos-gemkit` 0.1.0. The Gemfile
441
+ and workflow callers use the same release: the gem version is exact, and Actions
442
+ references pin its full commit SHA.
443
+
444
+ ```sh
436
445
  git clone https://github.com/ethos-link/crawlscope.git
437
446
  cd crawlscope
438
-
439
447
  bundle install
440
- bundle exec rake test
441
- bundle exec rake standard
442
- bundle exec rake
448
+ bundle exec lefthook install
449
+ bundle exec rake verify
443
450
  ```
444
451
 
445
- ### Git hooks
452
+ `rake verify` runs Standard, all Minitest tests, package validation and a git-cliff
453
+ smoke check. `rake` runs the same checks. Individual `rake test` and `rake standard`
454
+ tasks remain available, along with the `crawlscope:*` audit tasks above.
446
455
 
447
- We use [lefthook](https://lefthook.dev/) with the Ruby
448
- [commitlint](https://github.com/arandilopez/commitlint) gem to enforce
449
- Conventional Commits on every commit. We also use
450
- [Standard Ruby](https://standardrb.com/) to keep code style consistent. CI
451
- validates commit messages, Standard Ruby, tests, and git-cliff changelog
452
- generation on pull requests and pushes to main/master.
456
+ Hooks use Gemkit to block direct commits to main/master and validate Conventional
457
+ Commits. CI uses the same lint, test, package, changelog and commit checks.
458
+ GitLab sync has no caller because no target URL is configured.
453
459
 
454
- Run the hook installer once per clone:
460
+ To install a development build locally, run `bundle exec rake install`.
455
461
 
456
- ```bash
457
- bundle exec lefthook install
458
- ```
462
+ ## Release
459
463
 
460
- ### Install locally
464
+ Use `release:prepare` from clean, up-to-date `main`. It creates a conventional
465
+ release branch and review PR. **Merging the release PR starts publication through
466
+ GitHub Actions**; ordinary development PRs run verification only.
461
467
 
462
- ```bash
463
- rake install
464
- ```
468
+ ### RubyGems setup
465
469
 
466
- ## Release
470
+ Configure **crawlscope → Trusted publishers** on RubyGems with these values:
467
471
 
468
- Releases are tag-driven and published by GitHub Actions to RubyGems.
469
- Local release commands never publish directly.
472
+ | RubyGems field | Value |
473
+ |---|---|
474
+ | Repository owner | `ethos-link` |
475
+ | Repository name | `crawlscope` |
476
+ | Workflow filename | `release.yml` |
477
+ | Environment | `rubygems` |
478
+ | Workflow Repository Owner | `ethos-link` |
479
+ | Workflow Repository Name | `ethos-gemkit` |
470
480
 
471
- Install [git-cliff](https://git-cliff.org/) locally before preparing a
472
- release. The release task prepends the next `CHANGELOG.md` section from
473
- Conventional Commits.
481
+ The Workflow Repository fields are required because the publishing workflow lives
482
+ in Gemkit. Gemkit's own publisher does not authorize Crawlscope. The account ID
483
+ passed by the caller does not create publisher authorization.
474
484
 
475
- Before preparing a release, make sure you are on `main` or `master` with a
476
- clean worktree. If the release contains a breaking public-contract change,
477
- update `UPGRADE.md` with the host-app migration steps first.
485
+ Install Git, git-cliff and GitHub CLI, authenticate with `gh auth login`, and
486
+ install hooks as shown above. The `rubygems` GitHub environment must allow main
487
+ and version tags; repository rules must permit the workflow's annotated tags.
478
488
 
479
- Then run one of:
489
+ ### Prepare and publish
480
490
 
481
- ```bash
491
+ Update `UPGRADE.md` with host-app migration steps for contract changes before
492
+ preparing a release. Then run:
493
+
494
+ ```sh
495
+ git switch main
496
+ git pull --ff-only
497
+ bundle install
482
498
  bundle exec rake 'release:prepare[patch]'
483
- bundle exec rake 'release:prepare[minor]'
484
- bundle exec rake 'release:prepare[major]'
485
- bundle exec rake 'release:prepare[0.1.0]'
486
499
  ```
487
500
 
488
- The task will:
501
+ The default target is `patch`; `minor`, `major` and explicit versions are also
502
+ supported. The task updates the version, changelog and lockfile, verifies the gem,
503
+ commits with hooks enabled, pushes `chore/release-vX.Y.Z` and opens a release PR.
504
+ Review its metadata and notes, and wait for CI before merging.
489
505
 
490
- 1. Prepend the next `CHANGELOG.md` section with `git-cliff`.
491
- 1. Update `lib/crawlscope/version.rb`.
492
- 1. Commit the release changes.
493
- 1. Create and push the `vX.Y.Z` tag.
506
+ The workflow verifies and builds the exact release merge commit, creates an
507
+ annotated tag, publishes the same artifact and creates GitHub release notes.
508
+ No local publication or manual tag step is needed. Existing manually pushed
509
+ annotated version tags remain supported.
510
+
511
+ ### Failed publication
512
+
513
+ If credential setup reports `No trusted publisher configured for this workflow`
514
+ and `gem push` was skipped, correct the publisher fields above and rerun only
515
+ failed jobs in the original run:
516
+
517
+ ```sh
518
+ gh run rerun RUN_ID --repo ethos-link/crawlscope --failed
519
+ ```
494
520
 
495
- The `Release` workflow then runs tests, publishes the gem to RubyGems,
496
- and creates the GitHub release from the changelog entry.
521
+ The existing verified artifact and tag are reused. Do not run `release:prepare`
522
+ again, bump the version or replace the tag to recover from that authentication
523
+ failure. Failed release notes also use a failed-jobs retry without republishing.
524
+ For uploads with uncertain results, already-published versions or expired
525
+ artifacts, follow the [Gemkit recovery guide](https://github.com/ethos-link/ethos-gemkit#failures-and-retries).
497
526
 
498
527
  ## Contributing
499
528
 
data/UPGRADE.md ADDED
@@ -0,0 +1,138 @@
1
+ # Upgrade Guide
2
+
3
+ Use this file for host-app migration notes when a release changes public
4
+ contracts, required setup, component locals, generated assets, or runtime
5
+ behavior.
6
+
7
+ ## 0.9.0
8
+
9
+ ### Ruby 4 and optional Rails 8
10
+
11
+ Upgrade Ruby to 4.0 or newer before updating Crawlscope. Rails integrations now
12
+ require Rails 8 (`>= 8.0`, `< 9`). Upgrade the host Rails application when using
13
+ the generator or Railtie; plain Ruby and CLI callers do not need Rails.
14
+
15
+ Railties is no longer a runtime dependency. Rails applications must declare
16
+ Rails or Railties themselves. If Crawlscope loads before Rails, explicitly
17
+ require `crawlscope/rails` after the framework is available. Existing generated
18
+ initializers and `require "crawlscope/tasks"` loaders remain supported.
19
+
20
+ ### Release preparation
21
+
22
+ Development uses published Gemkit 0.1.0. Install the bundle and hooks with
23
+ `bundle install` and `bundle exec lefthook install`.
24
+ Run `release:prepare` from current main to open a verified release PR; merging
25
+ that PR triggers workflow publication. Local preparation no longer tags, pushes
26
+ main or bypasses hooks. Configure Crawlscope's RubyGems publisher as documented
27
+ in the README; the shared workflow does not inherit another gem's permission.
28
+
29
+ ## Next Release
30
+
31
+ ### Structured-data length errors include the measured size
32
+
33
+ String-length schema errors now include an optional `length` field with the
34
+ actual character count. Text reports show the measurement and limit, such as
35
+ `Article.headline: 125 characters; maximum 110`. Existing `field`, `issue`, and
36
+ `type` fields remain available, and `issue` retains the original validator
37
+ message. Applications that enforce exact error-object keys must accept `length`.
38
+
39
+ ### One warning per redirect or canonical mismatch
40
+
41
+ Sitemap redirects now emit only `sitemap_redirect_url`, rather than also emitting
42
+ `redirected_page`. Applications that match `redirected_page` must switch to
43
+ `sitemap_redirect_url`; `final_url` and final HTTP `status` remain in details.
44
+
45
+ Metadata and canonical-target checks skip redirect aliases, so the destination's
46
+ canonical is not compared with the redirect's original URL. Metadata checks still
47
+ run when the destination is itself in the crawl.
48
+
49
+ A directly served page with a different canonical emits one warning:
50
+ `non_canonical_page_in_sitemap` when it is in the sitemap, or `canonical_mismatch`
51
+ otherwise. Applications that previously counted both warnings should handle
52
+ either code as one mismatch.
53
+
54
+ Metadata length reports put the field and limit in the group heading; rows show
55
+ only the measured length. Server timing's page list now includes only durations
56
+ strictly greater than 50 ms. Aggregate timing statistics still include all
57
+ responses, and `result.server_timing_summary` retains all timing data.
58
+
59
+ ### Redirect URLs are excluded from uniqueness checks
60
+
61
+ Uniqueness checks now compare only HTML pages whose normalized requested and
62
+ final URLs match. Redirect aliases no longer produce duplicate-title,
63
+ duplicate-description, duplicate-text, or similar-text warnings from the
64
+ destination's content. Redirect issues remain in the crawl report. Separate
65
+ pages that serve identical content without a redirect are still checked.
66
+
67
+ No host-app configuration changes are required. Applications that count
68
+ uniqueness issues should expect fewer warnings when sitemap URLs redirect.
69
+
70
+ ### Clearer audit messages
71
+
72
+ Text reports now use plain-language group headings with severity counts and
73
+ show errors before warnings and notices. The repeated category summary is
74
+ removed. Structured-data errors show the type, field, and constraint on separate
75
+ lines (for example, `Article.headline: 125 characters; maximum 110`). Sitemap
76
+ redirects show the destination and its final HTTP status once, without the host
77
+ for same-origin URLs.
78
+ Canonical warnings now identify the canonical target and explain the mismatch.
79
+ Link warnings use `linked from` and `links to` to identify each URL's role.
80
+ Length and ratio warnings include the limit and units. Reports show every issue
81
+ and every related URL on separate lines. Duplicate-title and description values
82
+ are shown in full. Link rules retain all source and target URLs rather than
83
+ three samples. Missing-sitemap issues keep `source_url` and also provide
84
+ `source_urls` with all pages that link to the missing URL. Server timing retains
85
+ full descriptions and lists every page whose duration exceeds 50 ms.
86
+
87
+ Host applications that parse report text or issue messages must update their
88
+ matching patterns. Prefer issue codes and structured `details` for automation;
89
+ these retain their existing fields, including the original schema errors,
90
+ redirect status and final URL, and canonical href. No configuration changes are
91
+ required.
92
+
93
+ The former report limits `Reporter::MAX_ISSUES_PER_GROUP` and
94
+ `Rules::Links::MAX_SOURCES_IN_ERROR` are removed. Host applications that reference
95
+ these constants must remove those references.
96
+
97
+ ### Default sitemap is fetched over HTTP
98
+
99
+ Crawlscope no longer prefers `public/sitemap.xml` when validating a localhost
100
+ application. Without an explicit `SITEMAP` or configured `sitemap_path`, it now
101
+ fetches `/sitemap.xml` from the configured base URL so the crawl observes the
102
+ live application and database state.
103
+
104
+ The Rails installer now generates the same HTTP default. Regenerate or update
105
+ existing initializers that use `Rails.public_path.join("sitemap.xml")`.
106
+ Explicit local sitemap paths remain supported through `SITEMAP`, `--sitemap`,
107
+ or `config.sitemap_path`.
108
+
109
+ `CRAWLSCOPE_PROFILE_TOKEN` is now the portable default for standalone CLI, Rake,
110
+ Rails, and plain Ruby usage. Explicit `config.profile_token` values still take
111
+ precedence.
112
+
113
+ ### Server-Timing report output
114
+
115
+ No host configuration is required. When one or more responses publish a
116
+ `Server-Timing` header, the text report now includes an optional `Server Timing`
117
+ section. Host applications that parse report text should accept this additional
118
+ section.
119
+
120
+ Parsed metrics are available through `page.server_timing`, and aggregate data is
121
+ available through `result.server_timing_summary`. Crawlscope interprets `dur`
122
+ values as milliseconds and ignores malformed entries while reporting their
123
+ count.
124
+
125
+ ### Ruby 3.3 is now required
126
+
127
+ Crawlscope now depends on the current Async runtime for production async HTTP
128
+ fetching. Host applications must run Ruby 3.3 or newer before upgrading.
129
+
130
+ Recommended migration:
131
+
132
+ 1. Upgrade the host application runtime to Ruby 3.3 or newer.
133
+ 2. Run `bundle update crawlscope async async-http async-http-faraday`.
134
+ 3. Crawlscope now uses `FETCH_EXECUTOR=async` by default for HTTP crawling.
135
+ 4. Set `FETCH_EXECUTOR=threaded` or pass `--fetch-executor threaded` for a
136
+ conservative rollout or for explicit thread-pool execution.
137
+ 5. Browser rendering continues to use threaded execution by default because
138
+ async fetch execution is only supported with HTTP rendering.
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails"
4
+ require "rails/railtie"
5
+ require "crawlscope"
6
+ require "crawlscope/railtie"
@@ -1,5 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "rails"
4
+ require "rails/railtie"
5
+
6
+ unless Gem::Requirement.new(">= 8.0", "< 9").satisfied_by?(Gem.loaded_specs.fetch("railties").version)
7
+ raise LoadError, "crawlscope integration requires Rails 8.0 or newer within Rails 8"
8
+ end
9
+
3
10
  module Crawlscope
4
11
  class Railtie < Rails::Railtie
5
12
  rake_tasks do
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Crawlscope
4
- VERSION = "0.8.1"
4
+ VERSION = "0.9.0"
5
5
  end
data/lib/crawlscope.rb CHANGED
@@ -29,7 +29,7 @@ end
29
29
  Crawlscope.instance_variable_set(:@loader, Zeitwerk::Loader.for_gem)
30
30
  Crawlscope.loader.ignore("#{__dir__}/generators")
31
31
  Crawlscope.loader.ignore("#{__dir__}/tasks")
32
- Crawlscope.loader.ignore("#{__dir__}/crawlscope/railtie.rb")
32
+ Crawlscope.loader.ignore("#{__dir__}/crawlscope/railtie.rb", "#{__dir__}/crawlscope/rails.rb")
33
33
  Crawlscope.loader.ignore("#{__dir__}/crawlscope/tasks.rb")
34
34
  Crawlscope.loader.setup
35
35
 
@@ -15,6 +15,7 @@ class CrawlscopeLoaderTest < Minitest::Test
15
15
  script = <<~RUBY
16
16
  require "crawlscope"
17
17
 
18
+ abort "Rails loaded by the core" if defined?(Rails)
18
19
  loaded = $LOADED_FEATURES.grep(%r{/(?:async|faraday|json-schema|nokogiri)(?:/|\\.rb)})
19
20
  abort loaded.join("\\n") unless loaded.empty?
20
21
  RUBY
@@ -29,6 +30,30 @@ class CrawlscopeLoaderTest < Minitest::Test
29
30
  assert status.success?, stderr
30
31
  end
31
32
 
33
+ def test_explicit_rails_integration_loads_after_the_core_and_registers_tasks
34
+ script = <<~RUBY
35
+ require "crawlscope"
36
+ require "crawlscope/rails"
37
+
38
+ abort "Railtie missing" unless Crawlscope::Railtie < Rails::Railtie
39
+ app = Class.new(Rails::Application)
40
+ app.config.eager_load = false
41
+ app.load_tasks
42
+ %w[validate validate:ldjson validate:indexability validate:content_quality].each do |task|
43
+ abort "task missing: \#{task}" unless Rake::Task.task_defined?("crawlscope:\#{task}")
44
+ end
45
+ RUBY
46
+
47
+ _stdout, stderr, status = Open3.capture3(
48
+ RbConfig.ruby,
49
+ "-I#{File.expand_path("../../lib", __dir__)}",
50
+ "-e",
51
+ script
52
+ )
53
+
54
+ assert status.success?, stderr
55
+ end
56
+
32
57
  def test_task_entrypoint_registers_tasks
33
58
  script = <<~RUBY
34
59
  require "crawlscope/tasks"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crawlscope
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paulo Fidalgo
@@ -108,20 +108,6 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '1.16'
111
- - !ruby/object:Gem::Dependency
112
- name: railties
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '7.1'
118
- type: :runtime
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '7.1'
125
111
  - !ruby/object:Gem::Dependency
126
112
  name: zeitwerk
127
113
  requirement: !ruby/object:Gem::Requirement
@@ -150,20 +136,6 @@ dependencies:
150
136
  - - "~>"
151
137
  - !ruby/object:Gem::Version
152
138
  version: '5.0'
153
- - !ruby/object:Gem::Dependency
154
- name: rake
155
- requirement: !ruby/object:Gem::Requirement
156
- requirements:
157
- - - "~>"
158
- - !ruby/object:Gem::Version
159
- version: '13.0'
160
- type: :development
161
- prerelease: false
162
- version_requirements: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - "~>"
165
- - !ruby/object:Gem::Version
166
- version: '13.0'
167
139
  - !ruby/object:Gem::Dependency
168
140
  name: simplecov
169
141
  requirement: !ruby/object:Gem::Requirement
@@ -178,20 +150,6 @@ dependencies:
178
150
  - - "~>"
179
151
  - !ruby/object:Gem::Version
180
152
  version: '0.22'
181
- - !ruby/object:Gem::Dependency
182
- name: standard
183
- requirement: !ruby/object:Gem::Requirement
184
- requirements:
185
- - - "~>"
186
- - !ruby/object:Gem::Version
187
- version: '1.0'
188
- type: :development
189
- prerelease: false
190
- version_requirements: !ruby/object:Gem::Requirement
191
- requirements:
192
- - - "~>"
193
- - !ruby/object:Gem::Version
194
- version: '1.0'
195
153
  - !ruby/object:Gem::Dependency
196
154
  name: webmock
197
155
  requirement: !ruby/object:Gem::Requirement
@@ -219,6 +177,7 @@ files:
219
177
  - CHANGELOG.md
220
178
  - LICENSE.txt
221
179
  - README.md
180
+ - UPGRADE.md
222
181
  - exe/crawlscope
223
182
  - lib/crawlscope.rb
224
183
  - lib/crawlscope/browser.rb
@@ -235,6 +194,7 @@ files:
235
194
  - lib/crawlscope/issue.rb
236
195
  - lib/crawlscope/issue_collection.rb
237
196
  - lib/crawlscope/page.rb
197
+ - lib/crawlscope/rails.rb
238
198
  - lib/crawlscope/railtie.rb
239
199
  - lib/crawlscope/rake_tasks.rb
240
200
  - lib/crawlscope/reporter.rb
@@ -301,7 +261,6 @@ files:
301
261
  - test/performance/async_fetch_benchmark.rb
302
262
  - test/performance/fetch_executor_matrix.rb
303
263
  - test/performance/sitemap_expansion_benchmark.rb
304
- - test/release_task_test.rb
305
264
  - test/test_helper.rb
306
265
  homepage: https://www.ethos-link.com/opensource/crawlscope
307
266
  licenses:
@@ -323,7 +282,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
323
282
  requirements:
324
283
  - - ">="
325
284
  - !ruby/object:Gem::Version
326
- version: 3.3.0
285
+ version: '4.0'
327
286
  required_rubygems_version: !ruby/object:Gem::Requirement
328
287
  requirements:
329
288
  - - ">="
@@ -1,86 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "test_helper"
4
- require "rake"
5
-
6
- unless respond_to?(:release_version, true)
7
- load File.expand_path("../Rakefile", __dir__)
8
- end
9
-
10
- class ReleaseTaskTest < Minitest::Test
11
- def test_release_version_increments_patch_from_current_version
12
- major, minor, patch = Crawlscope::VERSION.split(".").map(&:to_i)
13
-
14
- assert_equal "#{major}.#{minor}.#{patch + 1}", release_version("patch")
15
- end
16
-
17
- def test_release_version_accepts_explicit_semantic_version
18
- assert_equal "0.3.0", release_version("0.3.0")
19
- end
20
-
21
- def test_validate_release_version_rejects_current_version
22
- error = assert_raises(ArgumentError) do
23
- validate_release_version!("0.2.7", "0.2.7")
24
- end
25
-
26
- assert_equal(
27
- "Release version 0.2.7 must be newer than current version 0.2.7.",
28
- error.message
29
- )
30
- end
31
-
32
- def test_validate_release_version_rejects_existing_local_tag
33
- @local_release_tag_exists = true
34
- @remote_release_tag_exists = false
35
-
36
- error = assert_raises(ArgumentError) do
37
- validate_release_version!("0.2.8", "0.2.7")
38
- end
39
-
40
- assert_equal "Release tag v0.2.8 already exists locally.", error.message
41
- end
42
-
43
- def test_validate_release_version_rejects_existing_remote_tag
44
- @local_release_tag_exists = false
45
- @remote_release_tag_exists = true
46
-
47
- error = assert_raises(ArgumentError) do
48
- validate_release_version!("0.2.8", "0.2.7")
49
- end
50
-
51
- assert_equal "Release tag v0.2.8 already exists on origin.", error.message
52
- end
53
-
54
- def test_remote_release_tag_command_asks_git_to_fail_when_no_tag_matches
55
- assert_equal(
56
- "git ls-remote --exit-code --tags origin refs/tags/v0.2.8",
57
- remote_release_tag_command("v0.2.8")
58
- )
59
- end
60
-
61
- def test_changelog_command_prepends_the_next_release
62
- assert_equal(
63
- [
64
- "git-cliff",
65
- "-c",
66
- "cliff.toml",
67
- "--unreleased",
68
- "--tag",
69
- "v0.2.8",
70
- "--prepend",
71
- "CHANGELOG.md"
72
- ],
73
- changelog_command("0.2.8")
74
- )
75
- end
76
-
77
- private
78
-
79
- def local_release_tag_exists?(_tag)
80
- @local_release_tag_exists || false
81
- end
82
-
83
- def remote_release_tag_exists?(_tag)
84
- @remote_release_tag_exists || false
85
- end
86
- end