Skip to content
This repository was archived by the owner on Feb 12, 2026. It is now read-only.

Commit e9fbe9a

Browse files
authored
Merge pull request #91 from buildkite/toote_harness_scaffolding
Harness scaffolding
2 parents 48690c7 + c9a8c13 commit e9fbe9a

File tree

5 files changed

+274
-0
lines changed

5 files changed

+274
-0
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# frozen_string_literal: true
2+
3+
require_relative '../translator'
4+
require_relative '../pipeline'
5+
require_relative '../pipeline/step'
6+
require_relative 'harness/steps/run'
7+
8+
module BK
9+
module Compat
10+
# Harness translation scaffolding
11+
class Harness
12+
include StepTranslator
13+
require 'yaml'
14+
15+
def self.name
16+
'Harness'
17+
end
18+
19+
def self.option
20+
'harness'
21+
end
22+
23+
def self.matches?(text)
24+
# sorting is important
25+
config = YAML.safe_load(text, aliases: true)
26+
mandatory_keys = %w[pipeline].freeze
27+
28+
if config.is_a?(Hash) && mandatory_keys & config.keys == mandatory_keys
29+
config['pipeline'].include?('stages')
30+
else
31+
false
32+
end
33+
end
34+
35+
def initialize(text, options = {})
36+
@config = YAML.safe_load(text, aliases: true)
37+
@options = options
38+
39+
BK::Compat::HarnessSteps::Run.new(register: method(:register_translator))
40+
end
41+
42+
def parse
43+
# map stages to groups
44+
grp = BK::Compat::GroupStep.new(
45+
label: @config['pipeline']['name'],
46+
key: @config['pipeline']['identifier']
47+
)
48+
49+
grp.steps = @config['pipeline']['stages'].map do |stage|
50+
parse_stage(**stage['stage'].transform_keys(&:to_sym))
51+
end
52+
53+
Pipeline.new(steps: [simplify_group(grp)])
54+
end
55+
56+
private
57+
58+
def simplify_group(group)
59+
# If there ended up being only 1 stage, skip the group and just
60+
# pull the steps out.
61+
if group.steps.length == 1
62+
group.steps.map! { |step| step.conditional = group.conditional }
63+
group = groups.steps.first
64+
end
65+
group
66+
end
67+
68+
def parse_stage(name:, identifier:, spec:, **_rest)
69+
BK::Compat::CommandStep.new(
70+
label: name,
71+
key: identifier
72+
).tap do |cmd|
73+
spec.dig('execution', 'steps').map do |step|
74+
cmd << translate_step(**step['step'].transform_keys(&:to_sym))
75+
end
76+
end
77+
end
78+
end
79+
end
80+
end
81+
82+
require_relative '../parsers'
83+
84+
BK::Compat::Parsers.register_plugin(BK::Compat::Harness)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# frozen_string_literal: true
2+
3+
require_relative '../../../pipeline/step'
4+
5+
module BK
6+
module Compat
7+
module HarnessSteps
8+
# Implementation of native step translation
9+
class Run
10+
def initialize(register:)
11+
register.call(
12+
method(:matcher),
13+
method(:translator)
14+
)
15+
end
16+
17+
private
18+
19+
def matcher(type:, **)
20+
type == 'Run'
21+
end
22+
23+
def translator(name:, identifier:, spec:, **_rest)
24+
BK::Compat::CommandStep.new(
25+
label: name,
26+
key: identifier,
27+
commands: [ spec['command'] ]
28+
)
29+
end
30+
end
31+
end
32+
end
33+
end
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
steps:
3+
- group: gha-test
4+
key: ghatest
5+
steps:
6+
- commands:
7+
- ' # step [] {:type=>"Background", :name=>"postgres-dependency", :identifier=>"postgresdependency",
8+
:spec=>{"connectorRef"=>"myDockerHubConnector", "image"=>"postgres:10.8", "shell"=>"Sh",
9+
"envVariables"=>{"POSTGRES_USER"=>"postgres", "POSTGRES_PASSWORD"=>"<+secrets.getValue(\"DbPasswordSecret\")>",
10+
"POSTGRES_DB"=>"postgres"}}} not implemented yet :('
11+
- echo "this runs on openjdk"
12+
label: stage1
13+
key: stage1
14+
- commands:
15+
- |-
16+
echo "pipeline var:" <+pipeline.variables.pipelinevar1>
17+
echo "project level var:" <+variable.proj_var>
18+
echo "secret example :" <+secrets.getValue("DbPasswordSecret")>
19+
label: stage2
20+
key: stage2
21+
- commands:
22+
- echo "Testing on <+matrix.testparam>"
23+
label: matrix stage
24+
key: matrix_stage
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
pipeline:
2+
name: gha-test
3+
identifier: ghatest
4+
projectIdentifier: gha_test
5+
orgIdentifier: default
6+
tags: {}
7+
properties:
8+
ci:
9+
codebase:
10+
connectorRef: account.myscm
11+
repoName: test
12+
build: <+input>
13+
stages:
14+
- stage:
15+
name: stage1
16+
identifier: stage1
17+
description: ""
18+
type: CI
19+
spec:
20+
cloneCodebase: true
21+
platform:
22+
os: Linux
23+
arch: Amd64
24+
runtime:
25+
type: Cloud
26+
spec: {}
27+
execution:
28+
steps:
29+
- step:
30+
type: Background
31+
name: postgres-dependency
32+
identifier: postgresdependency
33+
spec:
34+
connectorRef: myDockerHubConnector
35+
image: postgres:10.8
36+
shell: Sh
37+
envVariables:
38+
POSTGRES_USER: postgres
39+
POSTGRES_PASSWORD: <+secrets.getValue("DbPasswordSecret")>
40+
POSTGRES_DB: postgres
41+
- step:
42+
type: Run
43+
name: Run_1
44+
identifier: Run_1
45+
spec:
46+
connectorRef: myDockerHubConnector
47+
image: openjdk:17.0-jdk
48+
shell: Bash
49+
command: echo "this runs on openjdk"
50+
- stage:
51+
name: stage2
52+
identifier: stage2
53+
description: ""
54+
type: CI
55+
spec:
56+
cloneCodebase: true
57+
execution:
58+
steps:
59+
- step:
60+
type: Run
61+
name: Run_2
62+
identifier: Run_2
63+
spec:
64+
connectorRef: myDockerHubConnector
65+
image: node:13.0.0
66+
shell: Bash
67+
command: |-
68+
echo "pipeline var:" <+pipeline.variables.pipelinevar1>
69+
echo "project level var:" <+variable.proj_var>
70+
echo "secret example :" <+secrets.getValue("DbPasswordSecret")>
71+
platform:
72+
os: Linux
73+
arch: Amd64
74+
runtime:
75+
type: Cloud
76+
spec: {}
77+
- stage:
78+
name: matrix stage
79+
identifier: matrix_stage
80+
description: ""
81+
type: CI
82+
spec:
83+
cloneCodebase: true
84+
platform:
85+
os: Linux
86+
arch: Amd64
87+
runtime:
88+
type: Cloud
89+
spec: {}
90+
execution:
91+
steps:
92+
- step:
93+
type: Run
94+
name: Run_3
95+
identifier: Run_3
96+
spec:
97+
shell: Bash
98+
command: echo "Testing on <+matrix.testparam>"
99+
strategy:
100+
matrix:
101+
testparam:
102+
- node
103+
- python
104+
- ubuntu
105+
maxConcurrency: 3
106+
variables:
107+
- name: pipelinevar1
108+
type: String
109+
description: ""
110+
value: someval
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# frozen_string_literal: true
2+
3+
require_relative '../../../../../lib/bk/compat/parsers/harness'
4+
5+
RSpec.describe BK::Compat::Harness do
6+
let(:harness) { BK::Compat::Harness }
7+
8+
context 'it runs a snapshot test on each example' do
9+
directory_path = 'spec/lib/bk/compat/harness/examples'
10+
11+
Dir.glob("#{directory_path}/*").each do |file|
12+
next if File.directory?(file)
13+
14+
it "compares the generated pipeline for #{file} to the original" do
15+
content = File.read(file)
16+
parsed_content = harness.new(content).parse
17+
18+
actual = parsed_content.render(colors: false)
19+
expect(actual).to match_snapshot(file)
20+
end
21+
end
22+
end
23+
end

0 commit comments

Comments
 (0)