Skip to content

Commit 4182ec7

Browse files
authored
GitHub - clear branch protection when signing out (microsoft#182053)
1 parent 45b57b3 commit 4182ec7

File tree

2 files changed

+28
-23
lines changed

2 files changed

+28
-23
lines changed

extensions/github/src/auth.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ export function getOctokit(): Promise<Octokit> {
5959

6060
let _octokitGraphql: Promise<graphql> | undefined;
6161

62-
export async function getOctokitGraphql(): Promise<graphql> {
62+
export async function getOctokitGraphql(silent = false): Promise<graphql> {
6363
if (!_octokitGraphql) {
6464
try {
65-
const session = await authentication.getSession('github', scopes, { createIfNone: false });
65+
const session = await authentication.getSession('github', scopes, { silent });
6666

6767
if (!session) {
6868
throw new AuthenticationError('No GitHub authentication session available.');

extensions/github/src/branchProtection.ts

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -114,25 +114,32 @@ export class GithubBranchProtectionProvider implements BranchProtectionProvider
114114
// Restore branch protection from global state
115115
this.branchProtection = this.globalState.get<BranchProtection[]>(this.globalStateKey, []);
116116

117-
repository.status().then(() => this.updateRepositoryBranchProtection());
117+
repository.status().then(() => {
118+
authentication.onDidChangeSessions(e => {
119+
if (e.provider.id === 'github') {
120+
this.updateRepositoryBranchProtection(true);
121+
}
122+
});
123+
this.updateRepositoryBranchProtection();
124+
});
118125
}
119126

120127
provideBranchProtection(): BranchProtection[] {
121128
return this.branchProtection;
122129
}
123130

124-
private async getRepositoryDetails(owner: string, repo: string): Promise<GitHubRepository> {
125-
const graphql = await getOctokitGraphql();
131+
private async getRepositoryDetails(owner: string, repo: string, silent: boolean): Promise<GitHubRepository> {
132+
const graphql = await getOctokitGraphql(silent);
126133
const { repository } = await graphql<{ repository: GitHubRepository }>(REPOSITORY_QUERY, { owner, repo });
127134

128135
return repository;
129136
}
130137

131-
private async getRepositoryRulesets(owner: string, repo: string): Promise<RepositoryRuleset[]> {
138+
private async getRepositoryRulesets(owner: string, repo: string, silent: boolean): Promise<RepositoryRuleset[]> {
132139
const rulesets: RepositoryRuleset[] = [];
133140

134141
let cursor: string | undefined = undefined;
135-
const graphql = await getOctokitGraphql();
142+
const graphql = await getOctokitGraphql(silent);
136143

137144
while (true) {
138145
const { repository } = await graphql<{ repository: GitHubRepository }>(REPOSITORY_RULESETS_QUERY, { owner, repo, cursor });
@@ -151,10 +158,10 @@ export class GithubBranchProtectionProvider implements BranchProtectionProvider
151158
return rulesets;
152159
}
153160

154-
private async updateRepositoryBranchProtection(): Promise<void> {
155-
try {
156-
const branchProtection: BranchProtection[] = [];
161+
private async updateRepositoryBranchProtection(silent = false): Promise<void> {
162+
const branchProtection: BranchProtection[] = [];
157163

164+
try {
158165
for (const remote of this.repository.state.remotes) {
159166
const repository = getRepositoryFromUrl(remote.pushUrl ?? remote.fetchUrl ?? '');
160167

@@ -164,7 +171,7 @@ export class GithubBranchProtectionProvider implements BranchProtectionProvider
164171

165172
// Repository details
166173
this.logger.trace(`Fetching repository details for "${repository.owner}/${repository.repo}".`);
167-
const repositoryDetails = await this.getRepositoryDetails(repository.owner, repository.repo);
174+
const repositoryDetails = await this.getRepositoryDetails(repository.owner, repository.repo, silent);
168175

169176
// Check repository write permission
170177
if (repositoryDetails.viewerPermission !== 'ADMIN' && repositoryDetails.viewerPermission !== 'MAINTAIN' && repositoryDetails.viewerPermission !== 'WRITE') {
@@ -174,7 +181,7 @@ export class GithubBranchProtectionProvider implements BranchProtectionProvider
174181

175182
// Get repository rulesets
176183
const branchProtectionRules: BranchProtectionRule[] = [];
177-
const repositoryRulesets = await this.getRepositoryRulesets(repository.owner, repository.repo);
184+
const repositoryRulesets = await this.getRepositoryRulesets(repository.owner, repository.repo, silent);
178185

179186
for (const ruleset of repositoryRulesets) {
180187
branchProtectionRules.push({
@@ -193,19 +200,17 @@ export class GithubBranchProtectionProvider implements BranchProtectionProvider
193200
await this.globalState.update(this.globalStateKey, branchProtection);
194201
this.logger.trace(`Branch protection for "${this.repository.rootUri.toString()}": ${JSON.stringify(branchProtection)}.`);
195202
} catch (err) {
203+
this.logger.warn(`Failed to update repository branch protection: ${err.message}`);
204+
196205
if (err instanceof AuthenticationError) {
197-
// Since there is no GitHub authentication session available we need to wait
198-
// until the user signs in with their GitHub account so that we can query the
199-
// repository rulesets
200-
const disposable = authentication.onDidChangeSessions(e => {
201-
if (e.provider.id === 'github') {
202-
disposable.dispose();
203-
this.updateRepositoryBranchProtection();
204-
}
205-
});
206-
}
206+
// A GitHub authentication session could be missing if the user has not yet
207+
// signed in with their GitHub account or they have signed out. In this case
208+
// we have to clear the branch protection information.
209+
this.branchProtection = branchProtection;
210+
this._onDidChangeBranchProtection.fire(this.repository.rootUri);
207211

208-
this.logger.warn(`Failed to update repository branch protection: ${err.message}`);
212+
await this.globalState.update(this.globalStateKey, undefined);
213+
}
209214
}
210215
}
211216

0 commit comments

Comments
 (0)