Skip to content

ci: implement ci#369 change-detector — advisory-only version-selection heuristic - #375

Open
opoudjis wants to merge 1 commit into
mainfrom
feature/ci-369-version-advisory
Open

ci: implement ci#369 change-detector — advisory-only version-selection heuristic#375
opoudjis wants to merge 1 commit into
mainfrom
feature/ci-369-version-advisory

Conversation

@opoudjis

Copy link
Copy Markdown
Contributor

Refs #369

Implements the design brief from #369, per the 4 stated leans in our engagement comment (use-only-if-present public_api.txt; skip-on-first-release; workflow_dispatch-only dispatch scope; no repository_dispatch payload field).

What lands

  • .github/scripts/release-version-advisory.rb — Ruby, ~540 lines. Prism (stdlib) AST diff of lib/ between prev-tag and HEAD; multi-signal public/internal classification; markdown table + ::notice:: output. Exit 0 always (rescue clause backstops P1).
  • .github/scripts/test-fixtures/version-advisory/ — 5 fixtures + run-fixtures.sh (assert mode + --generate-golden bootstrap).
  • .github/workflows/test-version-advisory.yml — CI runs the fixture suite + a static-grep no-network-libs job enforcing AC 6.
  • .github/workflows/rubygems-release.yml — new version_advisory boolean input (default false, opt-in per P2). Three preflight steps guarded by if: inputs.version_advisory == true (fetch history / fetch script / run script). No behaviour change when consumers don't set the input.
  • docs/rubygems-release.md — new "Version advisory (opt-in)" section documenting signals, classification table, and Phase 2 limitations.

AC 4 coverage — 5 fixtures, all pass

Case Detected Suggested
a — internal removal Foo::internal_helper marked # @api private patch
b — public addition Foo::new_public_method marked # @api public minor
c — body-only public change Foo::public_thing body changed, same signature UNKNOWN
d — no change (comment-only) (no lib/ symbol changes detected) none
e — public signature broken Foo::transform positional arg removed major → demoted to minor per pre-1.0 SemVer §4

Golden expected.md per fixture. Assertion is byte-exact.

AC 5, 6

  • AC 5 (wrapper-friendly): output only via $GITHUB_STEP_SUMMARY + ::notice::. Only new input on the reusable is version_advisory. No wrapper-hostile plumbing.
  • AC 6 (no network calls): enforced statically by test-version-advisory.yml's no-network-libs job — fails CI if any of net/http / open-uri / faraday / httparty / excon / typhoeus / http appears as a require. Actual requires are Prism, Open3, JSON, Digest — all stdlib.

Phase 2 limitations (documented in script header + docs, not blockers)

  • class << self blocks not distinguished from instance methods.
  • attr_accessor/attr_reader/attr_writer accessors not extracted.
  • Inheritance and include/extend changes not detected.
  • define_method / class_eval metaprogramming not covered.

None impact AC 4 pass. All are extendable in follow-up PRs without shape change.

Test plan

  • ruby -c .github/scripts/release-version-advisory.rb — syntax OK.
  • bash .github/scripts/test-fixtures/version-advisory/run-fixtures.sh — 5/5 pass locally.
  • CI: test-version-advisory.yml runs on this PR.
  • Post-merge: consumers can opt in via with: { version_advisory: true } on their rubygems-release.yml call. Default off = no behaviour change for existing consumers.

🤖

…n heuristic

Implements the design brief from #369, per the 4 stated leans in our
engagement comment (use-only-if-present public_api.txt; skip on
first-release; workflow_dispatch-only dispatch scope; no repository_dispatch
payload field).

New:
- .github/scripts/release-version-advisory.rb: Ruby, Prism (stdlib) AST diff
  of lib/ between prev-tag and HEAD, multi-signal public/internal
  classification, markdown table + ::notice:: output. Exit 0 always.
- .github/scripts/test-fixtures/version-advisory/: 5 fixtures + assert-mode
  runner + generated expected.md golden files.
- .github/workflows/test-version-advisory.yml: CI fixture suite + AC 6
  static-grep no-network-libs enforcement.

Modified:
- .github/workflows/rubygems-release.yml: new `version_advisory` boolean
  input (default false, opt-in per P2); three preflight steps guarded by
  `if: inputs.version_advisory == true` (fetch history / fetch script / run).
  No behaviour change when consumers don't set the input.
- docs/rubygems-release.md: Inputs-table row + "Version advisory (opt-in)"
  section documenting signals, classification table, Phase 2 limitations.

AC 4 coverage: 5 fixtures (a-e) pass byte-exact against golden expected.md.
AC 5: output only via $GITHUB_STEP_SUMMARY + ::notice::; only one new input.
AC 6: enforced statically via CI grep.

Phase 2 (not blocking): class << self, attr_accessor family, inheritance
changes, define_method metaprogramming — documented in script header + docs.

Refs #369
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants