(ctx context.Context, digest string, orgIDs []uuid.UUID, p *pagination.CursorOptions, filters ...biz.GetFromRootFilter)
| 146 | } |
| 147 | |
| 148 | func (r *ReferrerRepo) GetFromRoot(ctx context.Context, digest string, orgIDs []uuid.UUID, p *pagination.CursorOptions, filters ...biz.GetFromRootFilter) (*biz.StoredReferrer, string, error) { |
| 149 | ctx, span := otelx.Start(ctx, referrerRepoTracer, "ReferrerRepo.GetFromRoot") |
| 150 | defer span.End() |
| 151 | |
| 152 | opts := &biz.GetFromRootFilters{} |
| 153 | for _, f := range filters { |
| 154 | f(opts) |
| 155 | } |
| 156 | |
| 157 | // Find the referrer from its digest + artifactType (optional) |
| 158 | // if there is more than 1 item we return ReferrerAmbiguous error |
| 159 | // filter by the allowed organizations and by the visibility of the attached workflows if needed |
| 160 | predicateReferrer := []predicate.Referrer{ |
| 161 | referrer.Digest(digest), |
| 162 | } |
| 163 | |
| 164 | // We might be filtering by the rootKind, this will prevent ambiguity |
| 165 | if opts.RootKind != nil { |
| 166 | predicateReferrer = append(predicateReferrer, referrer.Kind(*opts.RootKind)) |
| 167 | } |
| 168 | |
| 169 | // Prepare the workflow query predicate |
| 170 | predicateWF := []predicate.Workflow{ |
| 171 | workflow.DeletedAtIsNil(), workflow.HasOrganizationWith(organization.IDIn(orgIDs...)), |
| 172 | } |
| 173 | |
| 174 | // optionally attaching its visibility |
| 175 | if opts.Public != nil { |
| 176 | predicateWF = append(predicateWF, workflow.Public(*opts.Public)) |
| 177 | } |
| 178 | |
| 179 | // Attach the workflow predicate |
| 180 | predicateReferrer = append(predicateReferrer, referrer.HasWorkflowsWith(predicateWF...)) |
| 181 | |
| 182 | // If a project filter is requested, attach it as a subquery predicate. An attestation root |
| 183 | // matches only when its digest is one of the attestation_digests produced by a workflow run |
| 184 | // in the requested project (and, when set, version). Non-attestation roots pass through here |
| 185 | // and are validated later through their references. The cost is independent of how many |
| 186 | // runs the project has — Postgres executes it as a single semi-join, no Go-side digest list. |
| 187 | var projectPred predicate.Referrer |
| 188 | if opts.ProjectName != nil && *opts.ProjectName != "" { |
| 189 | version := "" |
| 190 | if opts.ProjectVersion != nil { |
| 191 | version = *opts.ProjectVersion |
| 192 | } |
| 193 | projectPred = r.projectScopePredicate(*opts.ProjectName, version, orgIDs, opts.ProjectIDs, opts.Public) |
| 194 | predicateReferrer = append(predicateReferrer, referrer.Or( |
| 195 | referrer.KindNEQ(biz.ReferrerAttestationType), |
| 196 | projectPred, |
| 197 | )) |
| 198 | } |
| 199 | |
| 200 | refs, err := r.data.DB.Referrer.Query().Where(predicateReferrer...).WithWorkflows().All(ctx) |
| 201 | if err != nil { |
| 202 | return nil, "", fmt.Errorf("failed to query referrer: %w", err) |
| 203 | } |
| 204 | |
| 205 | // No items found |
nothing calls this directly
no test coverage detected