edited ci file
This commit is contained in:
@@ -110,7 +110,7 @@ func (h *SBOMHandler) GetLatestDocument(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
// Generate triggers on-demand SBOM generation for a repo at a given ref/SHA.
|
||||
// POST /api/v1/repos/{owner}/{repo}/sbom/generate?ref=<sha-or-branch>
|
||||
// POST /api/v1/repos/{owner}/{repo}/sbom/generate?ref=<sha-or-branch>[&runID=<id>]
|
||||
func (h *SBOMHandler) Generate(w http.ResponseWriter, r *http.Request) {
|
||||
repoID, ok := resolveRepoID(h.db, w, r)
|
||||
if !ok {
|
||||
@@ -126,7 +126,12 @@ func (h *SBOMHandler) Generate(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
report, err := h.generator.GenerateOnDemand(repoID, sha)
|
||||
var runID int64
|
||||
if rid := r.URL.Query().Get("runID"); rid != "" {
|
||||
runID, _ = strconv.ParseInt(rid, 10, 64)
|
||||
}
|
||||
|
||||
report, err := h.generator.GenerateOnDemand(repoID, runID, sha)
|
||||
if err != nil {
|
||||
jsonError(w, "generation failed: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/go-chi/chi/v5"
|
||||
"xorm.io/xorm"
|
||||
|
||||
"github.com/forgeo/forgebucket/internal/api/middleware"
|
||||
"github.com/forgeo/forgebucket/internal/domain/scanning"
|
||||
"github.com/forgeo/forgebucket/internal/models"
|
||||
)
|
||||
@@ -52,7 +53,7 @@ func (h *ScanningHandler) DismissSecrets(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
// Get current user from session for audit trail.
|
||||
username := r.Context().Value("user").(string)
|
||||
username, _ := r.Context().Value(middleware.ContextKeyUsername).(string)
|
||||
|
||||
if err := h.scanner.DismissFindings(leakID, username); err != nil {
|
||||
jsonError(w, err.Error(), http.StatusNotFound)
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/go-chi/chi/v5"
|
||||
"xorm.io/xorm"
|
||||
|
||||
"github.com/forgeo/forgebucket/internal/api/middleware"
|
||||
"github.com/forgeo/forgebucket/internal/domain/vulnscan"
|
||||
"github.com/forgeo/forgebucket/internal/models"
|
||||
)
|
||||
@@ -49,6 +50,9 @@ func (h *VulnScanHandler) Scan(w http.ResponseWriter, r *http.Request) {
|
||||
jsonError(w, "scan failed: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if findings == nil {
|
||||
findings = []models.VulnerabilityFinding{}
|
||||
}
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
jsonOK(w, findings)
|
||||
}
|
||||
@@ -68,7 +72,7 @@ func (h *VulnScanHandler) Dismiss(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
username := r.Context().Value("user").(string)
|
||||
username, _ := r.Context().Value(middleware.ContextKeyUsername).(string)
|
||||
|
||||
if err := h.scanner.DismissFindings(findingID, username); err != nil {
|
||||
jsonError(w, err.Error(), http.StatusNotFound)
|
||||
|
||||
@@ -206,13 +206,13 @@ func New(cfg *config.Config, engine *xorm.Engine, store sessions.Store, bus even
|
||||
})
|
||||
r.Get("/artifacts", artifactH.List)
|
||||
r.With(csrf).Post("/artifacts", artifactH.Upload)
|
||||
r.Get("/sbom", sbomH.GetForRun)
|
||||
r.Get("/sbom/document", sbomH.GetDocumentForRun)
|
||||
})
|
||||
})
|
||||
r.Get("/artifacts/{artifactID}/download", artifactH.Download)
|
||||
r.Get("/artifacts/{artifactID}/signature", artifactH.GetSignature)
|
||||
r.Get("/artifacts/{artifactID}/verify", artifactH.VerifySignature)
|
||||
r.Get("/sbom", sbomH.GetForRun)
|
||||
r.Get("/sbom/document", sbomH.GetDocumentForRun)
|
||||
r.Route("/members", func(r chi.Router) {
|
||||
r.Get("/", memberH.List)
|
||||
r.With(csrf).Post("/", memberH.Add)
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"xorm.io/xorm"
|
||||
|
||||
"github.com/forgeo/forgebucket/internal/domain/sbom"
|
||||
"github.com/forgeo/forgebucket/internal/events"
|
||||
"github.com/forgeo/forgebucket/internal/models"
|
||||
)
|
||||
@@ -17,12 +18,13 @@ import (
|
||||
// advances the DAG as jobs complete. It does NOT execute jobs directly —
|
||||
// that is the RunnerManager's responsibility.
|
||||
type Orchestrator struct {
|
||||
db *xorm.Engine
|
||||
bus events.EventBus
|
||||
db *xorm.Engine
|
||||
bus events.EventBus
|
||||
sbomGen *sbom.Generator
|
||||
}
|
||||
|
||||
func NewOrchestrator(db *xorm.Engine, bus events.EventBus) *Orchestrator {
|
||||
return &Orchestrator{db: db, bus: bus}
|
||||
func NewOrchestrator(db *xorm.Engine, bus events.EventBus, sbomGen *sbom.Generator) *Orchestrator {
|
||||
return &Orchestrator{db: db, bus: bus, sbomGen: sbomGen}
|
||||
}
|
||||
|
||||
// Start subscribes to relevant NATS subjects and blocks until ctx is cancelled.
|
||||
@@ -142,7 +144,11 @@ func (o *Orchestrator) createRun(repo models.Repository, evt events.PushEvent, w
|
||||
|
||||
// Create job + step records for every job in the workflow.
|
||||
for jobName, wfJob := range wf.Jobs {
|
||||
needsJSON, _ := json.Marshal([]string(wfJob.Needs))
|
||||
needs := []string(wfJob.Needs)
|
||||
if needs == nil {
|
||||
needs = []string{}
|
||||
}
|
||||
needsJSON, _ := json.Marshal(needs)
|
||||
job := &models.PipelineJob{
|
||||
RunID: run.ID,
|
||||
Name: jobName,
|
||||
@@ -231,6 +237,9 @@ func (o *Orchestrator) advanceDAG(runID, jobID int64, result string) {
|
||||
run.FinishedAt = &now
|
||||
o.db.ID(run.ID).Cols("status", "finished_at").Update(&run) //nolint:errcheck
|
||||
o.bus.Publish(events.SubjectPipelineCompleted, events.PipelineEvent{RunID: run.ID, RepoID: run.RepoID, Status: "succeeded", At: now}) //nolint:errcheck
|
||||
if o.sbomGen != nil {
|
||||
go o.sbomGen.GenerateOnDemand(run.RepoID, run.ID, run.TriggerSHA)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -86,24 +86,32 @@ func (g *Generator) generateForRun(runID, repoID int64) {
|
||||
|
||||
// GenerateOnDemand generates an SBOM for a specific repo + SHA and stores it
|
||||
// (or returns the cached one if the SHA was already processed).
|
||||
func (g *Generator) GenerateOnDemand(repoID int64, sha string) (*models.SBOMReport, error) {
|
||||
// Return cached report for this exact SHA if one already exists.
|
||||
var existing models.SBOMReport
|
||||
if found, _ := g.db.Where("repo_id = ? AND sha = ?", repoID, sha).Get(&existing); found {
|
||||
return &existing, nil
|
||||
}
|
||||
|
||||
func (g *Generator) GenerateOnDemand(repoID, runID int64, ref string) (*models.SBOMReport, error) {
|
||||
var repo models.Repository
|
||||
if found, _ := g.db.ID(repoID).Get(&repo); !found {
|
||||
return nil, fmt.Errorf("repo %d not found", repoID)
|
||||
}
|
||||
|
||||
// Resolve the ref to a full commit SHA — ref can be a branch name, tag, etc.
|
||||
sha, err := gitdomain.RevParse(repo.DiskPath, ref)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("rev-parse %s: %w", ref, err)
|
||||
}
|
||||
|
||||
// Return cached report for this exact SHA + runID if one already exists.
|
||||
// Without runID in the cache key, a prior on-demand generation (runID=0)
|
||||
// would shadow subsequent per-run generation requests.
|
||||
var existing models.SBOMReport
|
||||
if found, _ := g.db.Where("repo_id = ? AND sha = ? AND run_id = ?", repoID, sha, runID).Get(&existing); found {
|
||||
return &existing, nil
|
||||
}
|
||||
|
||||
doc, err := Generate(repo.DiskPath, repo.Name, sha)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
report, err := g.persistAndReturn(repoID, 0, sha, doc)
|
||||
report, err := g.persistAndReturn(repoID, runID, sha, doc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user