Files
ubicloud/helpers/runtime.rb
Enes Cakir 0793488ad4 Set the workflow_job data when fetching from the GitHub API
Normally, we fill the `workflow_job` data of the `GithubRunner` object
when the `workflow_job.in_progress` webhook event is delivered. [^1]

We use the `head_branch` value from this data at runtime endpoints to
validate the scope cache.

When this data is missing, we try to retrieve it from the GitHub API.
Since this operation can be costly, it's a good idea to persist the
result if the same job needs the same data before the webhook is
delivered. [^2]

Since the GitHub API doesn't have proper filtering, we fetch all jobs of
the workflow run and try to find the corresponding runner using the
`runner_name` property.

As another improvement, we can update the `workflow_job` column of the
all jobs we've already fetched. We can use code similar to this, but I
need to think more about it. It's not good practice to update resources
other than the prog's subject, so we should also prevent to overwrite
existing data.

```ruby
jobs.each do |job|
  GithubRunner.where(id: UBID.to_uuid(job[:runner_name]), workflow_job: nil).update(workflow_job: Sequel.pg_jsonb(job.except("steps")))
end
```

[^1]: d4c19c2bec/routes/webhook/github.rb (L90)
[^2]: d4c19c2bec/routes/runtime/github.rb (L28)
2025-05-13 22:51:38 +03:00

38 lines
1.4 KiB
Ruby

# frozen_string_literal: true
class Clover < Roda
def get_runtime_jwt_payload
return unless (v = request.env["HTTP_AUTHORIZATION"])
jwt_token = v.sub(%r{\ABearer:?\s+}, "")
begin
JWT.decode(jwt_token, Config.clover_runtime_token_secret, true, {algorithm: "HS256"})[0]
rescue JWT::DecodeError
end
end
def get_scope_from_github(runner, run_id)
log_context = {runner_ubid: runner.ubid, repository_ubid: runner.repository.ubid, run_id: run_id}
if run_id.nil? || run_id.empty?
Clog.emit("The run_id is blank") { {runner_scope_failure: log_context} }
return
end
Clog.emit("Get runner scope from GitHub API") { {get_runner_scope: log_context} }
begin
client = Github.installation_client(runner.installation.installation_id)
jobs = client.workflow_run_jobs(runner.repository_name, run_id)[:jobs]
rescue Octokit::ClientError, Octokit::ServerError, Faraday::ConnectionFailed, Faraday::TimeoutError => ex
log_context[:expection] = Util.exception_to_hash(ex)
Clog.emit("Could not list the jobs of the workflow run ") { {runner_scope_failure: log_context} }
return
end
if (job = jobs.find { it[:runner_name] == runner.ubid })
runner.this.update(workflow_job: Sequel.pg_jsonb(job.except("steps")))
job[:head_branch]
else
Clog.emit("The workflow run does not have given runner") { {runner_scope_failure: log_context} }
nil
end
end
end