Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci-tools: Add rtool subcommand to download artifact #1643

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions ci-tools/github-runner/artifact.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Licensed under the Apache-2.0 license

package runner

import (
"context"
"errors"
"io"
"log"
"net/http"
"os"

"github.com/google/go-github/v53/github"
)

func findArtifact(artifacts *github.ArtifactList, name string) (*github.Artifact, error) {
for _, artifact := range artifacts.Artifacts {
if artifact.GetName() == name {
return artifact, nil
}
}
return nil, errors.New("could not find artifact")
}

func DownloadArtifact(ctx context.Context, client *github.Client, workflowFilename string, artifactName string) error {
repo := "caliptra-sw"
workflow, _, err := client.Actions.GetWorkflowByFileName(ctx, githubOrg, repo, workflowFilename)
if err != nil {
return err
}
runs, _, err := client.Actions.ListWorkflowRunsByID(ctx, githubOrg, repo, workflow.GetID(), &github.ListWorkflowRunsOptions{
Branch: "main",
Status: "completed",
})
if err != nil {
return err
}
if len(runs.WorkflowRuns) == 0 {
return errors.New("no workflow runs")
}
artifacts, _, err := client.Actions.ListWorkflowRunArtifacts(ctx, githubOrg, repo, runs.WorkflowRuns[0].GetID(), &github.ListOptions{})
if err != nil {
return err
}
artifact, err := findArtifact(artifacts, artifactName)
if err != nil {
return err
}
url, _, err := client.Actions.DownloadArtifact(ctx, githubOrg, repo, artifact.GetID(), true)
if err != nil {
return err
}
resp, err := http.Get(url.String())
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
log.Fatalf("Response failed with status code: %d and body %s\n", resp.StatusCode, body)
}
_, err = io.Copy(os.Stdout, resp.Body)
if err != nil {
return errors.New("unable to copy response body")
}
return nil
}
68 changes: 67 additions & 1 deletion ci-tools/github-runner/cmd/rtool/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,55 @@ import (
)

func usage() {
fmt.Println("Usage: this_cmd [launch|serve|build_image|cleanup|jitconfig]")
fmt.Println(`Usage: rtool [launch|serve|build_image|cleanup|jitconfig|download_artifact] [...]

download_artifact <app_id> <installation_id> <workflow_filename> <artifact_name>

Download an artifact from Github. A cronjob on the fpga_boss machine
can use this command to download the latest output of the "Build FPGA SD
image" workflow, which fpga_boss will flash the FPGAs with between every
job.

launch <machine_types_csv> <app_id> <installation_id>

Launch a GCE VM of the specified machine-type and give it new just-in-time
GHA runner creds. This is typically used for testing logic used by the GCF
locally.

jitconfig <machine_types_csv> <app_id> <installation_id> <runner_name>

Register a new GHA just-in-time runner and return the jitconfig. This can
be used with "fpga_boss serve" to get a fresh jitconfig for an FPGA if you
have app credentials.

receive_jitconfig

Pull a jitconfig from the GCP queue; may block if none is available.

publish_jitconfig <machine_types_csv> <app_id> <installation_id>

Generate a new jitconfig and put it into the GCP queue; for testing only.

serve

Launch a webserver locally to serve the cloud functions. Can be useful for testing.

cleanup

Cleanup old or stuck GCE VMs. Mostly used for testing GCF logic.

build_image

Launch a GCE VM to build a fresh GitHub Runner image with all the latest
security fixes. Mostly used for testing GCF logic.

Common arguments:

app_id: The Github app_id to use. This is typically 379559 (the [Caliptra]
GHA-runners-on-GCP app)

installation_id: The installation id of the app
`)
}

func main() {
Expand Down Expand Up @@ -45,6 +93,24 @@ func main() {
if err != nil {
log.Fatal(err)
}
} else if os.Args[1] == "download_artifact" {
korran marked this conversation as resolved.
Show resolved Hide resolved
appId, err := strconv.ParseInt(os.Args[2], 10, 64)
if err != nil {
log.Fatal(err)
}
installationId, err := strconv.ParseInt(os.Args[3], 10, 64)
if err != nil {
log.Fatal(err)
}
client, err := hello.GithubClient(appId, installationId)
if err != nil {
log.Fatal(err)
}
err = hello.DownloadArtifact(ctx, client, os.Args[4], os.Args[5])
if err != nil {
log.Fatal(err)
}
return
} else if os.Args[1] == "launch" || os.Args[1] == "jitconfig" || os.Args[1] == "publish_jitconfig" {
if len(os.Args) <= 4 {
log.Fatalf("usage: this_cmd launch <machine_type> <app_id> <installation_id>")
Expand Down
Loading