Compare commits
3 Commits
425e423753
...
2cbc6adebc
| Author | SHA1 | Date | |
|---|---|---|---|
| 2cbc6adebc | |||
| f1e2f0c03f | |||
| 19f31a87fb |
8
.github/workflows/release.yml
vendored
8
.github/workflows/release.yml
vendored
@@ -14,11 +14,11 @@ jobs:
|
|||||||
id-token: write
|
id-token: write
|
||||||
environment: release
|
environment: release
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- uses: ruby/setup-ruby@v1
|
- uses: ruby/setup-ruby@003a5c4d8d6321bd302e38f6f0ec593f77f06600 # v1.319.0
|
||||||
with:
|
with:
|
||||||
ruby-version: ruby
|
ruby-version: "4.0"
|
||||||
bundler-cache: true
|
bundler-cache: true
|
||||||
- uses: rubygems/release-gem@v1
|
- uses: rubygems/release-gem@052cc82692552de3ef2b81fd670e41d13cba8092 # v1.4.0
|
||||||
|
|||||||
6
.github/workflows/test.yml
vendored
6
.github/workflows/test.yml
vendored
@@ -12,12 +12,12 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
ruby: ["3.2", "3.3", "3.4"]
|
ruby: ["3.2", "3.3", "3.4", "4.0"]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
|
|
||||||
- name: Set up Ruby ${{ matrix.ruby }}
|
- name: Set up Ruby ${{ matrix.ruby }}
|
||||||
uses: ruby/setup-ruby@v1
|
uses: ruby/setup-ruby@003a5c4d8d6321bd302e38f6f0ec593f77f06600 # v1.319.0
|
||||||
with:
|
with:
|
||||||
ruby-version: ${{ matrix.ruby }}
|
ruby-version: ${{ matrix.ruby }}
|
||||||
bundler-cache: true
|
bundler-cache: true
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ require "yaml"
|
|||||||
class ReleaseWorkflowTest < Minitest::Test
|
class ReleaseWorkflowTest < Minitest::Test
|
||||||
ROOT = File.expand_path("..", __dir__)
|
ROOT = File.expand_path("..", __dir__)
|
||||||
WORKFLOW_PATH = File.join(ROOT, ".github", "workflows", "release.yml")
|
WORKFLOW_PATH = File.join(ROOT, ".github", "workflows", "release.yml")
|
||||||
|
SETUP_RUBY_ACTION = "ruby/setup-ruby@003a5c4d8d6321bd302e38f6f0ec593f77f06600"
|
||||||
|
RELEASE_GEM_ACTION = "rubygems/release-gem@052cc82692552de3ef2b81fd670e41d13cba8092"
|
||||||
|
|
||||||
def workflow
|
def workflow
|
||||||
@workflow ||= YAML.safe_load(File.read(WORKFLOW_PATH), aliases: false)
|
@workflow ||= YAML.safe_load(File.read(WORKFLOW_PATH), aliases: false)
|
||||||
@@ -27,7 +29,10 @@ class ReleaseWorkflowTest < Minitest::Test
|
|||||||
)
|
)
|
||||||
|
|
||||||
steps = push_job.fetch("steps")
|
steps = push_job.fetch("steps")
|
||||||
assert_equal 1, steps.count { |step| step["uses"] == "rubygems/release-gem@v1" }
|
setup_ruby = steps.find { |step| step["uses"] == SETUP_RUBY_ACTION }
|
||||||
|
|
||||||
|
assert_equal "4.0", setup_ruby.dig("with", "ruby-version")
|
||||||
|
assert_equal 1, steps.count { |step| step["uses"] == RELEASE_GEM_ACTION }
|
||||||
refute steps.any? { |step| step.fetch("run", "").match?(/\bgem\s+push\b/) }
|
refute steps.any? { |step| step.fetch("run", "").match?(/\bgem\s+push\b/) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
67
test/workflow_contract_test.rb
Normal file
67
test/workflow_contract_test.rb
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "minitest/autorun"
|
||||||
|
require "yaml"
|
||||||
|
|
||||||
|
class WorkflowContractTest < Minitest::Test
|
||||||
|
ROOT = File.expand_path("..", __dir__)
|
||||||
|
WORKFLOW_DIRECTORY = File.join(ROOT, ".github", "workflows")
|
||||||
|
TEST_WORKFLOW_PATH = File.join(WORKFLOW_DIRECTORY, "test.yml")
|
||||||
|
ACTION_PINS = {
|
||||||
|
"actions/checkout" => "9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0",
|
||||||
|
"ruby/setup-ruby" => "003a5c4d8d6321bd302e38f6f0ec593f77f06600",
|
||||||
|
"rubygems/release-gem" => "052cc82692552de3ef2b81fd670e41d13cba8092"
|
||||||
|
}.freeze
|
||||||
|
|
||||||
|
def test_matrix_covers_every_supported_ruby
|
||||||
|
workflow = YAML.safe_load(File.read(TEST_WORKFLOW_PATH), aliases: false)
|
||||||
|
versions = workflow.dig("jobs", "test", "strategy", "matrix", "ruby")
|
||||||
|
|
||||||
|
assert_equal %w[3.2 3.3 3.4 4.0], versions
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_every_third_party_action_uses_its_reviewed_commit
|
||||||
|
action_uses = Dir[File.join(WORKFLOW_DIRECTORY, "*.{yml,yaml}")].sort.flat_map do |path|
|
||||||
|
workflow = YAML.safe_load(File.read(path), aliases: false)
|
||||||
|
|
||||||
|
workflow_uses(workflow)
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal 5, action_uses.length
|
||||||
|
action_uses.each do |action_use|
|
||||||
|
action, separator, revision = action_use.rpartition("@")
|
||||||
|
|
||||||
|
assert_equal "@", separator
|
||||||
|
assert_equal ACTION_PINS.fetch(action), revision
|
||||||
|
assert_match(/\A[0-9a-f]{40}\z/, revision)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_action_discovery_only_reads_workflow_action_locations
|
||||||
|
workflow = YAML.safe_load(<<~YAML, aliases: false)
|
||||||
|
jobs:
|
||||||
|
reusable:
|
||||||
|
uses: "owner/workflow@revision"
|
||||||
|
with:
|
||||||
|
uses: ordinary-job-input
|
||||||
|
test:
|
||||||
|
steps:
|
||||||
|
- uses: "owner/action@revision"
|
||||||
|
with:
|
||||||
|
uses: ordinary-step-input
|
||||||
|
YAML
|
||||||
|
|
||||||
|
assert_equal %w[owner/workflow@revision owner/action@revision], workflow_uses(workflow)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def workflow_uses(node)
|
||||||
|
node.fetch("jobs").values.flat_map do |job|
|
||||||
|
action_uses = job.key?("uses") ? [job.fetch("uses")] : []
|
||||||
|
step_uses = job.fetch("steps", []).filter_map { |step| step["uses"] }
|
||||||
|
|
||||||
|
action_uses.concat(step_uses)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user