Skip to content

Commit a1bc449

Browse files
authored
Merge pull request #51 from github/aegis
Apply updates for GitHub AE.
2 parents abe96c5 + 52a76d0 commit a1bc449

File tree

2 files changed

+28
-8
lines changed

2 files changed

+28
-8
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ From a machine with access to both GitHub.com and GitHub Enterprise Server use t
2020

2121
**Required Arguments:**
2222
* `--destination-url` - The URL of the GitHub Enterprise Server instance to push the Action to.
23-
* `--destination-token` - A [Personal Access Token](https://docs.github.com/en/enterprise/user/github/authenticating-to-github/creating-a-personal-access-token) for the destination GitHub Enterprise Server instance. The token should be granted at least the `public_repo` scope. If the destination repository is in an organization that does not yet exist or that you are not an owner of, your token will need to have the `site_admin` scope in order to create the organization. The organization can also be created manually or an existing organization used.
23+
* `--destination-token` - A [Personal Access Token](https://docs.github.com/en/enterprise/user/github/authenticating-to-github/creating-a-personal-access-token) for the destination GitHub Enterprise Server instance. If the destination repository is in an organization that does not yet exist or that you are not an owner of, your token will need to have the `site_admin` scope in order to create the organization or update the repository in it. The organization can also be created manually or an existing organization that you own can be used, in which case the `repo` and `workflow` scopes are sufficient.
2424

2525
**Optional Arguments:**
2626
* `--cache-dir` - A temporary directory in which to store data downloaded from GitHub.com before it is uploaded to GitHub Enterprise Server. If not specified a directory next to the sync tool will be used.
@@ -43,7 +43,7 @@ Now use the `./codeql-action-sync push` command to upload the CodeQL Action and
4343

4444
**Required Arguments:**
4545
* `--destination-url` - The URL of the GitHub Enterprise Server instance to push the Action to.
46-
* `--destination-token` - A [Personal Access Token](https://docs.github.com/en/enterprise/user/github/authenticating-to-github/creating-a-personal-access-token) for the destination GitHub Enterprise Server instance. The token should be granted at least the `public_repo` scope. If the destination repository is in an organization that does not yet exist or that you are not an owner of, your token will need to have the `site_admin` scope in order to create the organization. The organization can also be created manually or an existing organization used.
46+
* `--destination-token` - A [Personal Access Token](https://docs.github.com/en/enterprise/user/github/authenticating-to-github/creating-a-personal-access-token) for the destination GitHub Enterprise Server instance. If the destination repository is in an organization that does not yet exist or that you are not an owner of, your token will need to have the `site_admin` scope in order to create the organization or update the repository in it. The organization can also be created manually or an existing organization that you own can be used, in which case the `repo` and `workflow` scopes are sufficient.
4747

4848
**Optional Arguments:**
4949
* `--cache-dir` - The directory to which the Action was previously downloaded.

internal/push/push.go

+26-6
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ const errorInvalidDestinationToken = "The destination token you've provided is n
3939

4040
const enterpriseAPIPath = "/api/v3"
4141
const enterpriseUploadsPath = "/api/uploads"
42+
const enterpriseVersionHeaderKey = "X-GitHub-Enterprise-Version"
43+
const enterpriseAegisVersionHeaderValue = "GitHub AE"
4244

4345
type pushService struct {
4446
ctx context.Context
@@ -48,11 +50,21 @@ type pushService struct {
4850
destinationRepositoryOwner string
4951
destinationToken *oauth2.Token
5052
actionsAdminUser string
53+
aegis bool
5154
force bool
5255
pushSSH bool
5356
}
5457

5558
func (pushService *pushService) createRepository() (*github.Repository, error) {
59+
minimumRepositoryScope := "public_repo"
60+
acceptableRepositoryScopes := []string{"public_repo", "repo"}
61+
desiredVisibility := "public"
62+
if pushService.aegis {
63+
minimumRepositoryScope = "repo"
64+
acceptableRepositoryScopes = []string{"repo"}
65+
desiredVisibility = "internal"
66+
}
67+
5668
log.Debug("Ensuring repository exists...")
5769
user, response, err := pushService.githubEnterpriseClient.Users.Get(pushService.ctx, "")
5870
if err != nil {
@@ -93,7 +105,7 @@ func (pushService *pushService) createRepository() (*github.Repository, error) {
93105
}
94106
if err != nil && githubapiutil.HasAnyScope(response, "site_admin") {
95107
log.Debugf("No access to destination organization. Switching to impersonation token for %s...", pushService.actionsAdminUser)
96-
impersonationToken, _, err := pushService.githubEnterpriseClient.Admin.CreateUserImpersonation(pushService.ctx, pushService.actionsAdminUser, &github.ImpersonateUserOptions{Scopes: []string{"public_repo", "workflow"}})
108+
impersonationToken, _, err := pushService.githubEnterpriseClient.Admin.CreateUserImpersonation(pushService.ctx, pushService.actionsAdminUser, &github.ImpersonateUserOptions{Scopes: []string{minimumRepositoryScope, "workflow"}})
97109
if err != nil {
98110
return nil, errors.Wrap(err, "Failed to impersonate Actions admin user.")
99111
}
@@ -117,22 +129,28 @@ func (pushService *pushService) createRepository() (*github.Repository, error) {
117129
HasWiki: github.Bool(false),
118130
HasDownloads: github.Bool(false),
119131
Archived: github.Bool(false),
120-
Private: github.Bool(false),
132+
}
133+
if repository.GetVisibility() != desiredVisibility {
134+
// For some reason if you provide a visibility it must be different than the current visibility.
135+
// It seems to be the only property that behaves this way, so we have to treat is specially...
136+
desiredRepositoryProperties.Visibility = github.String(desiredVisibility)
121137
}
122138
if response.StatusCode == http.StatusNotFound {
139+
log.Debug("Repository does not exist. Creating it...")
123140
repository, response, err = pushService.githubEnterpriseClient.Repositories.Create(pushService.ctx, destinationOrganization, &desiredRepositoryProperties)
124141
if err != nil {
125-
if response.StatusCode == http.StatusNotFound && !githubapiutil.HasAnyScope(response, "public_repo", "repo") {
126-
return nil, usererrors.New("The destination token you have provided does not have the `public_repo` scope.")
142+
if response.StatusCode == http.StatusNotFound && !githubapiutil.HasAnyScope(response, acceptableRepositoryScopes...) {
143+
return nil, fmt.Errorf("The destination token you have provided does not have the `%s` scope.", minimumRepositoryScope)
127144
}
128145
return nil, errors.Wrap(err, "Error creating destination repository.")
129146
}
130147
} else {
148+
log.Debug("Repository already exists. Updating its metadata...")
131149
repository, response, err = pushService.githubEnterpriseClient.Repositories.Edit(pushService.ctx, pushService.destinationRepositoryOwner, pushService.destinationRepositoryName, &desiredRepositoryProperties)
132150
if err != nil {
133151
if response.StatusCode == http.StatusNotFound {
134-
if !githubapiutil.HasAnyScope(response, "public_repo", "repo") {
135-
return nil, usererrors.New("The destination token you have provided does not have the `public_repo` scope.")
152+
if !githubapiutil.HasAnyScope(response, acceptableRepositoryScopes...) {
153+
return nil, fmt.Errorf("The destination token you have provided does not have the `%s` scope.", minimumRepositoryScope)
136154
} else {
137155
return nil, fmt.Errorf("You don't have permission to update the repository at %s/%s. If you wish to update the bundled CodeQL Action please provide a token with the `site_admin` scope.", pushService.destinationRepositoryOwner, pushService.destinationRepositoryName)
138156
}
@@ -389,6 +407,7 @@ func Push(ctx context.Context, cacheDirectory cachedirectory.CacheDirectory, des
389407
return errors.Wrap(err, "Error creating GitHub Enterprise client.")
390408
}
391409
}
410+
aegis := rootResponse.Header.Get(enterpriseVersionHeaderKey) == enterpriseAegisVersionHeaderValue
392411

393412
destinationRepositorySplit := strings.Split(destinationRepository, "/")
394413
destinationRepositoryOwner := destinationRepositorySplit[0]
@@ -402,6 +421,7 @@ func Push(ctx context.Context, cacheDirectory cachedirectory.CacheDirectory, des
402421
destinationRepositoryName: destinationRepositoryName,
403422
destinationToken: &token,
404423
actionsAdminUser: actionsAdminUser,
424+
aegis: aegis,
405425
force: force,
406426
pushSSH: pushSSH,
407427
}

0 commit comments

Comments
 (0)