| 138 | } |
| 139 | |
| 140 | func createRelease(httpClient *http.Client, repo ghrepo.Interface, params map[string]any) (*shared.Release, error) { |
| 141 | bodyBytes, err := json.Marshal(params) |
| 142 | if err != nil { |
| 143 | return nil, err |
| 144 | } |
| 145 | |
| 146 | path, err := safeurl.JoinPath("repos", repo.RepoOwner(), repo.RepoName(), "releases") |
| 147 | if err != nil { |
| 148 | return nil, err |
| 149 | } |
| 150 | |
| 151 | // Check if we received a 404 while attempting to create a release without |
| 152 | // the workflow scope, and if so, return an error message that explains a possible |
| 153 | // solution to the user. |
| 154 | // |
| 155 | // If the same file (with both the same path and contents) exists |
| 156 | // on another branch in the repo, releases with workflow file changes can be |
| 157 | // created without the workflow scope. Otherwise, the workflow scope is |
| 158 | // required to create the release, but the API does not indicate this criteria |
| 159 | // beyond returning a 404. |
| 160 | // |
| 161 | // https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps#available-scopes |
| 162 | var newRelease shared.Release |
| 163 | // TODO(api-client-rollout) |
| 164 | // This line of code is part of a mechanical roll out of the api client. |
| 165 | // As a follow up, consider whether the api client can be injected to this call site, rather than constructed |
| 166 | err = api.NewClientFromHTTP(httpClient).REST(repo.RepoHost(), http.MethodPost, path.String(), bytes.NewBuffer(bodyBytes), &newRelease) |
| 167 | if err != nil { |
| 168 | var httpErr api.HTTPError |
| 169 | if errors.As(err, &httpErr) && |
| 170 | httpErr.StatusCode == http.StatusNotFound && |
| 171 | !tokenHasWorkflowScope(httpErr.Headers) { |
| 172 | normalizedHostname := ghauth.NormalizeHostname(httpErr.RequestURL.Hostname()) |
| 173 | return nil, &errMissingRequiredWorkflowScope{ |
| 174 | Hostname: normalizedHostname, |
| 175 | } |
| 176 | } |
| 177 | return nil, err |
| 178 | } |
| 179 | return &newRelease, nil |
| 180 | } |
| 181 | |
| 182 | func publishRelease(httpClient *http.Client, host string, releaseURL safeurl.SafeURL, discussionCategory string, isLatest *bool) (*shared.Release, error) { |
| 183 | params := map[string]any{"draft": false} |