hastci 0.1.0 → 0.1.1

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: 27d28132add51197aa671ad6dd4144aa7867e6872fd04759b8a58c8374902916
4
- data.tar.gz: 4837752bbdddb42aade93d3ccc557bdb6cf7a199a733be643c0b8c429184eb43
3
+ metadata.gz: f7d454a50c04ff233b5cb379678b92e0aeaa04f9e7b116307a7e89678fbe26be
4
+ data.tar.gz: 1228b92fd4be4ba6717af33b0c0c771cb1e17315eb8648b04397d4b13ab74d6a
5
5
  SHA512:
6
- metadata.gz: 0be5ec737d6fe6196af175de67c21edcd39fe30463602ff757b98dadc0141583799ea89459eeec834fffd08e93d319212767067f3f728be446af7c84c8b96cec
7
- data.tar.gz: 2f4118eb2e35de8edff25e53be4d6930d345366bb13f796656609f88ed29cc9063047caf6d46d0361b07172960a3abf08dd29a07d1585a928ede084c2b14da84
6
+ metadata.gz: d731397122285e81f9bc3b410474bf7ff828b2d16f32320d2150c055e46b245a86f50a7e15f67bcd943365549de360e61783f49794db2ff901c193cb131e9ce7
7
+ data.tar.gz: 7e25b68ce224aae1953c5eb797b073dc4900fad52d3537cc497543ef7cb5215d319edef657d3f6a9a6f3358d5ec5b2d8aa8f816b8f85bb672c682cb45f8b016c
data/devenv.lock CHANGED
@@ -3,10 +3,10 @@
3
3
  "devenv": {
4
4
  "locked": {
5
5
  "dir": "src/modules",
6
- "lastModified": 1764877862,
6
+ "lastModified": 1766921574,
7
7
  "owner": "cachix",
8
8
  "repo": "devenv",
9
- "rev": "5b6cb65d7dec827badc6bbceeac934931beb7f4e",
9
+ "rev": "02c9dcf3e050400d8101057f9f00ec458af7c959",
10
10
  "type": "github"
11
11
  },
12
12
  "original": {
@@ -19,10 +19,10 @@
19
19
  "flake-compat": {
20
20
  "flake": false,
21
21
  "locked": {
22
- "lastModified": 1764712249,
22
+ "lastModified": 1766929376,
23
23
  "owner": "edolstra",
24
24
  "repo": "flake-compat",
25
- "rev": "3b279e4317ccfa4865356387935310531357d919",
25
+ "rev": "236f248441a986331cda53b039e7f9fd96e03635",
26
26
  "type": "github"
27
27
  },
28
28
  "original": {
@@ -34,10 +34,10 @@
34
34
  "flake-compat_2": {
35
35
  "flake": false,
36
36
  "locked": {
37
- "lastModified": 1764712249,
37
+ "lastModified": 1766929376,
38
38
  "owner": "edolstra",
39
39
  "repo": "flake-compat",
40
- "rev": "3b279e4317ccfa4865356387935310531357d919",
40
+ "rev": "236f248441a986331cda53b039e7f9fd96e03635",
41
41
  "type": "github"
42
42
  },
43
43
  "original": {
@@ -72,10 +72,10 @@
72
72
  ]
73
73
  },
74
74
  "locked": {
75
- "lastModified": 1763988335,
75
+ "lastModified": 1765911976,
76
76
  "owner": "cachix",
77
77
  "repo": "git-hooks.nix",
78
- "rev": "50b9238891e388c9fdc6a5c49e49c42533a1b5ce",
78
+ "rev": "b68b780b69702a090c8bb1b973bab13756cc7a27",
79
79
  "type": "github"
80
80
  },
81
81
  "original": {
@@ -128,10 +128,10 @@
128
128
  ]
129
129
  },
130
130
  "locked": {
131
- "lastModified": 1764740760,
131
+ "lastModified": 1766728475,
132
132
  "owner": "bobvanderlinden",
133
133
  "repo": "nixpkgs-ruby",
134
- "rev": "6747e142e5689bb156d47c9c90fe1596ecd246cb",
134
+ "rev": "f167828eab19c3a7e3faa066a140d92e307f7b16",
135
135
  "type": "github"
136
136
  },
137
137
  "original": {
@@ -18,13 +18,15 @@ module HastCI
18
18
  private_constant :DEFAULT_MAX_RETRIES, :DEFAULT_INITIAL_BACKOFF, :DEFAULT_MAX_BACKOFF,
19
19
  :DEFAULT_KEEP_ALIVE_TIMEOUT, :DEFAULT_OPEN_TIMEOUT, :DEFAULT_READ_TIMEOUT, :DEFAULT_WRITE_TIMEOUT
20
20
 
21
+ API_PATH_PREFIX = "/api/v1"
22
+
21
23
  # Separate connections allow concurrent operations without blocking.
22
24
  # E.g., heartbeat can continue while the main thread waits on a claim.
23
25
  CONNECTION_DEFAULT = :default
24
26
  CONNECTION_HEARTBEAT = :heartbeat
25
27
  CONNECTION_ACK = :ack
26
28
 
27
- private_constant :CONNECTION_DEFAULT, :CONNECTION_HEARTBEAT, :CONNECTION_ACK
29
+ private_constant :API_PATH_PREFIX, :CONNECTION_DEFAULT, :CONNECTION_HEARTBEAT, :CONNECTION_ACK
28
30
 
29
31
  def initialize(config:, sleeper: Kernel.method(:sleep), max_retries: nil, random: Random.new)
30
32
  @config = config
@@ -56,52 +58,54 @@ module HastCI
56
58
  commit_sha: @config.commit_sha
57
59
  )
58
60
  response = ensure_hash_response(
59
- post_json("/runs/init", {
61
+ post_json("#{API_PATH_PREFIX}/runs", {
60
62
  run_key: run_key,
61
63
  worker_id: worker_id,
62
64
  commit_sha: commit_sha
63
65
  }),
64
- context: "/runs/init"
66
+ context: "#{API_PATH_PREFIX}/runs"
65
67
  )
66
68
 
67
69
  {
68
- run_id: fetch_required(response, "run_id", context: "/runs/init"),
69
- status: fetch_required(response, "status", context: "/runs/init").to_sym,
70
- role: fetch_required(response, "role", context: "/runs/init").to_sym
70
+ run_id: fetch_required(response, "run_id", context: "#{API_PATH_PREFIX}/runs"),
71
+ status: fetch_required(response, "status", context: "#{API_PATH_PREFIX}/runs").to_sym,
72
+ role: fetch_required(response, "role", context: "#{API_PATH_PREFIX}/runs").to_sym
71
73
  }
72
74
  end
73
75
 
74
76
  def seed(run_id:, tasks:)
75
- post_json("/runs/#{run_id}/seed", {
77
+ post_json("#{API_PATH_PREFIX}/runs/#{run_id}/seed", {
76
78
  tasks: tasks.map { |name| {name: name} }
77
79
  })
78
80
  end
79
81
 
80
82
  def run_status(run_id:)
81
- response = ensure_hash_response(get_json("/runs/#{run_id}/status"), context: "/runs/status")
83
+ response = ensure_hash_response(
84
+ get_json("#{API_PATH_PREFIX}/runs/#{run_id}"),
85
+ context: "#{API_PATH_PREFIX}/runs/:run_id"
86
+ )
82
87
 
83
88
  {
84
- status: fetch_required(response, "status", context: "/runs/status").to_sym
89
+ status: fetch_required(response, "status", context: "#{API_PATH_PREFIX}/runs/:run_id").to_sym
85
90
  }
86
91
  end
87
92
 
88
93
  def claim(
89
- run_key: @config.run_key,
94
+ run_id:,
90
95
  worker_id: @config.worker_id,
91
96
  batch: @config.claim_batch_size
92
97
  )
93
98
  response = ensure_hash_response(
94
- post_json("/tasks/claim?batch=#{batch}", {
95
- run_key: run_key,
99
+ post_json("#{API_PATH_PREFIX}/runs/#{run_id}/claims?batch=#{batch}", {
96
100
  worker_id: worker_id
97
101
  }),
98
- context: "/tasks/claim"
102
+ context: "#{API_PATH_PREFIX}/runs/:run_id/claims"
99
103
  )
100
104
 
101
105
  tasks = Array(response.fetch("tasks", [])).map do |task_data|
102
106
  Task.new(
103
- id: fetch_required(task_data, "id", context: "/tasks/claim"),
104
- name: fetch_required(task_data, "name", context: "/tasks/claim")
107
+ id: fetch_required(task_data, "id", context: "#{API_PATH_PREFIX}/runs/:run_id/claims"),
108
+ name: fetch_required(task_data, "name", context: "#{API_PATH_PREFIX}/runs/:run_id/claims")
105
109
  )
106
110
  end
107
111
 
@@ -114,7 +118,7 @@ module HastCI
114
118
  end
115
119
 
116
120
  def ack(task_id:, status:, duration_s:, logs:)
117
- post_json("/tasks/#{task_id}/ack", {
121
+ post_json("#{API_PATH_PREFIX}/tasks/#{task_id}/acknowledgment", {
118
122
  status: status.to_s,
119
123
  duration_s: duration_s,
120
124
  logs: logs
@@ -122,11 +126,10 @@ module HastCI
122
126
  end
123
127
 
124
128
  def heartbeat(
125
- run_key: @config.run_key,
129
+ run_id:,
126
130
  worker_id: @config.worker_id
127
131
  )
128
- post_json("/workers/heartbeat", {
129
- run_key: run_key,
132
+ post_json("#{API_PATH_PREFIX}/runs/#{run_id}/heartbeats", {
130
133
  worker_id: worker_id
131
134
  }, pool: CONNECTION_HEARTBEAT)
132
135
 
@@ -176,12 +179,13 @@ module HastCI
176
179
 
177
180
  elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time if @config.debug
178
181
  log_response(response, request_id, elapsed) if @config.debug
182
+ log_error_body(response, request_id) if @config.debug && response.code.to_i >= 400
179
183
  parse_response(response)
180
184
  end
181
185
  end
182
186
 
183
187
  def log_request(request, request_id)
184
- HastCI.logger.debug("[#{request_id}] #{request.method} #{request.path}")
188
+ HastCI.logger.debug("[#{request_id}] #{request.method} #{@base_url}#{request.path}")
185
189
  return unless request.body
186
190
 
187
191
  body_preview = if request.body.length > 200
@@ -196,6 +200,15 @@ module HastCI
196
200
  HastCI.logger.debug("[#{request_id}] Response: #{response.code} (#{(elapsed_s * 1000).round}ms)")
197
201
  end
198
202
 
203
+ def log_error_body(response, request_id)
204
+ body = response.body.to_s
205
+ return if body.strip.empty?
206
+
207
+ summary = body.match(/No route matches[^<]*/)&.to_s
208
+ body_preview = summary || ((body.length > 200) ? "#{body[0, 200]}... (#{body.length} bytes)" : body)
209
+ HastCI.logger.debug("[#{request_id}] Error body: #{body_preview}")
210
+ end
211
+
199
212
  def log_retry(request_id, attempt)
200
213
  HastCI.logger.debug("[#{request_id}] Retry attempt #{attempt}")
201
214
  end
data/lib/hastci/config.rb CHANGED
@@ -4,7 +4,7 @@ require "securerandom"
4
4
 
5
5
  module HastCI
6
6
  class Config
7
- DEFAULT_API_BASE_URL = "https://hastci.com/api"
7
+ DEFAULT_API_BASE_URL = "https://hastci.com"
8
8
  DEFAULT_CLAIM_BATCH_SIZE = 10
9
9
  DEFAULT_HEARTBEAT_INTERVAL = 15
10
10
  DEFAULT_SEEDING_TIMEOUT = 300
@@ -7,8 +7,9 @@ module HastCI
7
7
 
8
8
  private_constant :SHUTDOWN_TIMEOUT, :MAX_CONSECUTIVE_FAILURES
9
9
 
10
- def initialize(api_client:, error_collector: nil, interval: 15)
10
+ def initialize(api_client:, run_id:, error_collector: nil, interval: 15)
11
11
  @api_client = api_client
12
+ @run_id = run_id
12
13
  @error_collector = error_collector
13
14
  @interval = interval
14
15
  @running = false
@@ -64,7 +65,7 @@ module HastCI
64
65
  end
65
66
 
66
67
  def send_heartbeat
67
- @api_client.heartbeat
68
+ @api_client.heartbeat(run_id: @run_id)
68
69
  @consecutive_failures = 0
69
70
  rescue RetryExhaustedError, FatalApiError => e
70
71
  @error_collector&.report(e)
@@ -203,6 +203,7 @@ module HastCI
203
203
 
204
204
  @heartbeat = Heartbeat.new(
205
205
  api_client: @api_client,
206
+ run_id: @run_id,
206
207
  interval: @config.heartbeat_interval,
207
208
  error_collector: @error_collector
208
209
  )
@@ -233,7 +234,7 @@ module HastCI
233
234
  max_size: @buffer_max_size,
234
235
  fetcher: lambda { |limit|
235
236
  batch_size = [limit, @config.claim_batch_size].min
236
- @api_client.claim(batch: batch_size)
237
+ @api_client.claim(run_id: @run_id, batch: batch_size)
237
238
  },
238
239
  error_collector: @error_collector,
239
240
  poll_interval: @poll_interval,
@@ -2,6 +2,6 @@
2
2
 
3
3
  # :nocov:
4
4
  module HastCI
5
- VERSION = "0.1.0"
5
+ VERSION = "0.1.1"
6
6
  end
7
7
  # :nocov:
@@ -11,7 +11,7 @@
11
11
  "providerState": "a valid API key",
12
12
  "request": {
13
13
  "method": "post",
14
- "path": "/runs/init",
14
+ "path": "/api/v1/runs",
15
15
  "headers": {
16
16
  "Authorization": "Bearer test-api-key",
17
17
  "Content-Type": "application/json"
@@ -39,13 +39,14 @@
39
39
  "Content-Type": "application/json"
40
40
  },
41
41
  "body": {
42
- "run_id": "run-uuid-123",
42
+ "run_id": "018f1234-5678-7000-8000-123456789abc",
43
43
  "status": "seeding",
44
44
  "role": "seeder"
45
45
  },
46
46
  "matchingRules": {
47
47
  "$.body.run_id": {
48
- "match": "type"
48
+ "match": "regex",
49
+ "regex": "^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
49
50
  },
50
51
  "$.body.status": {
51
52
  "match": "regex",
@@ -63,7 +64,7 @@
63
64
  "providerState": "an invalid API key",
64
65
  "request": {
65
66
  "method": "post",
66
- "path": "/runs/init",
67
+ "path": "/api/v1/runs",
67
68
  "headers": {
68
69
  "Authorization": "Bearer invalid-api-key",
69
70
  "Content-Type": "application/json"
@@ -91,7 +92,10 @@
91
92
  "Content-Type": "application/json"
92
93
  },
93
94
  "body": {
94
- "error": "Unauthorized"
95
+ "error": {
96
+ "code": "unauthorized",
97
+ "message": "Unauthorized"
98
+ }
95
99
  },
96
100
  "matchingRules": {
97
101
  "$.body.error": {
@@ -105,9 +109,15 @@
105
109
  "providerState": "a run exists",
106
110
  "request": {
107
111
  "method": "get",
108
- "path": "/runs/run-123/status",
112
+ "path": "/api/v1/runs/018f1234-5678-7000-8000-123456789abc",
109
113
  "headers": {
110
114
  "Authorization": "Bearer test-api-key"
115
+ },
116
+ "matchingRules": {
117
+ "$.path": {
118
+ "match": "regex",
119
+ "regex": "^\\/api\\/v1\\/runs\\/[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
120
+ }
111
121
  }
112
122
  },
113
123
  "response": {
@@ -131,7 +141,7 @@
131
141
  "providerState": "a run exists",
132
142
  "request": {
133
143
  "method": "post",
134
- "path": "/runs/run-123/seed",
144
+ "path": "/api/v1/runs/018f1234-5678-7000-8000-123456789abc/seed",
135
145
  "headers": {
136
146
  "Authorization": "Bearer test-api-key",
137
147
  "Content-Type": "application/json"
@@ -145,6 +155,12 @@
145
155
  "name": "spec/models/post_spec.rb"
146
156
  }
147
157
  ]
158
+ },
159
+ "matchingRules": {
160
+ "$.path": {
161
+ "match": "regex",
162
+ "regex": "^\\/api\\/v1\\/runs\\/[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\\/seed$"
163
+ }
148
164
  }
149
165
  },
150
166
  "response": {
@@ -163,15 +179,20 @@
163
179
  "providerState": "tasks are available",
164
180
  "request": {
165
181
  "method": "post",
166
- "path": "/tasks/claim",
182
+ "path": "/api/v1/runs/018f1234-5678-7000-8000-123456789abc/claims",
167
183
  "query": "batch=10",
168
184
  "headers": {
169
185
  "Authorization": "Bearer test-api-key",
170
186
  "Content-Type": "application/json"
171
187
  },
172
188
  "body": {
173
- "run_key": "test-run-key",
174
189
  "worker_id": "worker-0"
190
+ },
191
+ "matchingRules": {
192
+ "$.path": {
193
+ "match": "regex",
194
+ "regex": "^\\/api\\/v1\\/runs\\/[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\\/claims$"
195
+ }
175
196
  }
176
197
  },
177
198
  "response": {
@@ -182,27 +203,45 @@
182
203
  "body": {
183
204
  "tasks": [
184
205
  {
185
- "id": "task-1",
206
+ "id": "018f1234-5678-7000-8000-123456789def",
186
207
  "name": "spec/models/user_spec.rb"
187
208
  },
188
209
  {
189
- "id": "task-2",
210
+ "id": "018f1234-5678-7000-8000-123456789012",
190
211
  "name": "spec/models/post_spec.rb"
212
+ },
213
+ {
214
+ "id": "018f1234-5678-7000-8000-123456789013",
215
+ "name": "spec/models/comment_spec.rb"
216
+ },
217
+ {
218
+ "id": "018f1234-5678-7000-8000-123456789014",
219
+ "name": "spec/models/profile_spec.rb"
191
220
  }
192
221
  ],
193
- "queue_state": "ready",
222
+ "queue_state": "draining",
194
223
  "remaining": {
195
- "queued": 10,
196
- "assigned": 2,
197
- "completed": 5
224
+ "queued": 0,
225
+ "assigned": 4,
226
+ "completed": 0
198
227
  }
199
228
  },
200
229
  "matchingRules": {
201
230
  "$.body.tasks[0].id": {
202
- "match": "type"
231
+ "match": "regex",
232
+ "regex": "^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
203
233
  },
204
234
  "$.body.tasks[1].id": {
205
- "match": "type"
235
+ "match": "regex",
236
+ "regex": "^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
237
+ },
238
+ "$.body.tasks[2].id": {
239
+ "match": "regex",
240
+ "regex": "^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
241
+ },
242
+ "$.body.tasks[3].id": {
243
+ "match": "regex",
244
+ "regex": "^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
206
245
  },
207
246
  "$.body.remaining.queued": {
208
247
  "match": "type"
@@ -221,15 +260,20 @@
221
260
  "providerState": "queue is empty but not drained",
222
261
  "request": {
223
262
  "method": "post",
224
- "path": "/tasks/claim",
263
+ "path": "/api/v1/runs/018f1234-5678-7000-8000-123456789abc/claims",
225
264
  "query": "batch=10",
226
265
  "headers": {
227
266
  "Authorization": "Bearer test-api-key",
228
267
  "Content-Type": "application/json"
229
268
  },
230
269
  "body": {
231
- "run_key": "test-run-key",
232
270
  "worker_id": "worker-0"
271
+ },
272
+ "matchingRules": {
273
+ "$.path": {
274
+ "match": "regex",
275
+ "regex": "^\\/api\\/v1\\/runs\\/[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\\/claims$"
276
+ }
233
277
  }
234
278
  },
235
279
  "response": {
@@ -244,14 +288,20 @@
244
288
  "providerState": "queue is drained",
245
289
  "request": {
246
290
  "method": "post",
247
- "path": "/tasks/claim",
291
+ "path": "/api/v1/runs/018f1234-5678-7000-8000-123456789abc/claims",
248
292
  "query": "batch=10",
249
293
  "headers": {
250
- "Authorization": "Bearer test-api-key"
294
+ "Authorization": "Bearer test-api-key",
295
+ "Content-Type": "application/json"
251
296
  },
252
297
  "body": {
253
- "run_key": "test-run-key",
254
298
  "worker_id": "worker-0"
299
+ },
300
+ "matchingRules": {
301
+ "$.path": {
302
+ "match": "regex",
303
+ "regex": "^\\/api\\/v1\\/runs\\/[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\\/claims$"
304
+ }
255
305
  }
256
306
  },
257
307
  "response": {
@@ -264,12 +314,62 @@
264
314
  }
265
315
  }
266
316
  },
317
+ {
318
+ "description": "a request to claim from cancelled run",
319
+ "providerState": "run is cancelled",
320
+ "request": {
321
+ "method": "post",
322
+ "path": "/api/v1/runs/018f1234-5678-7000-8000-123456789abc/claims",
323
+ "query": "batch=10",
324
+ "headers": {
325
+ "Authorization": "Bearer test-api-key",
326
+ "Content-Type": "application/json"
327
+ },
328
+ "body": {
329
+ "worker_id": "worker-0"
330
+ },
331
+ "matchingRules": {
332
+ "$.path": {
333
+ "match": "regex",
334
+ "regex": "^\\/api\\/v1\\/runs\\/[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\\/claims$"
335
+ }
336
+ }
337
+ },
338
+ "response": {
339
+ "status": 200,
340
+ "headers": {
341
+ "Content-Type": "application/json"
342
+ },
343
+ "body": {
344
+ "tasks": [
345
+ ],
346
+ "queue_state": "cancelled",
347
+ "remaining": {
348
+ "queued": 0,
349
+ "assigned": 0,
350
+ "completed": 5
351
+ },
352
+ "should_stop": true
353
+ },
354
+ "matchingRules": {
355
+ "$.body.remaining.queued": {
356
+ "match": "type"
357
+ },
358
+ "$.body.remaining.assigned": {
359
+ "match": "type"
360
+ },
361
+ "$.body.remaining.completed": {
362
+ "match": "type"
363
+ }
364
+ }
365
+ }
366
+ },
267
367
  {
268
368
  "description": "a request to ack a task",
269
369
  "providerState": "a task exists",
270
370
  "request": {
271
371
  "method": "post",
272
- "path": "/tasks/task-123/ack",
372
+ "path": "/api/v1/tasks/018f1234-5678-7000-8000-123456789def/acknowledgment",
273
373
  "headers": {
274
374
  "Authorization": "Bearer test-api-key",
275
375
  "Content-Type": "application/json"
@@ -282,6 +382,12 @@
282
382
  "failures": [
283
383
  ]
284
384
  }
385
+ },
386
+ "matchingRules": {
387
+ "$.path": {
388
+ "match": "regex",
389
+ "regex": "^\\/api\\/v1\\/tasks\\/[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\\/acknowledgment$"
390
+ }
285
391
  }
286
392
  },
287
393
  "response": {
@@ -299,14 +405,19 @@
299
405
  "providerState": "a worker exists",
300
406
  "request": {
301
407
  "method": "post",
302
- "path": "/workers/heartbeat",
408
+ "path": "/api/v1/runs/018f1234-5678-7000-8000-123456789abc/heartbeats",
303
409
  "headers": {
304
410
  "Authorization": "Bearer test-api-key",
305
411
  "Content-Type": "application/json"
306
412
  },
307
413
  "body": {
308
- "run_key": "test-run-key",
309
414
  "worker_id": "worker-0"
415
+ },
416
+ "matchingRules": {
417
+ "$.path": {
418
+ "match": "regex",
419
+ "regex": "^\\/api\\/v1\\/runs\\/[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\\/heartbeats$"
420
+ }
310
421
  }
311
422
  },
312
423
  "response": {
@@ -321,7 +432,7 @@
321
432
  "providerState": "resource not found",
322
433
  "request": {
323
434
  "method": "get",
324
- "path": "/runs/invalid-run/status",
435
+ "path": "/api/v1/runs/invalid-run",
325
436
  "headers": {
326
437
  "Authorization": "Bearer test-api-key"
327
438
  }
@@ -337,7 +448,7 @@
337
448
  "providerState": "server error",
338
449
  "request": {
339
450
  "method": "post",
340
- "path": "/runs/init",
451
+ "path": "/api/v1/runs",
341
452
  "headers": {
342
453
  "Authorization": "Bearer test-api-key",
343
454
  "Content-Type": "application/json"
@@ -359,7 +470,7 @@
359
470
  "providerState": "unexpected redirect",
360
471
  "request": {
361
472
  "method": "post",
362
- "path": "/runs/init",
473
+ "path": "/api/v1/runs",
363
474
  "headers": {
364
475
  "Authorization": "Bearer test-api-key",
365
476
  "Content-Type": "application/json"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hastci
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wojciech Wrona