From e6caab1eb95431b438a35d5a36c2745b13f6cd97 Mon Sep 17 00:00:00 2001 From: Josh Gross Date: Mon, 30 Jan 2023 16:37:08 -0500 Subject: [PATCH 1/2] Support shared organization secrets and variables --- .../src/context-providers/secrets.ts | 28 ++++++++++++++- .../src/context-providers/variables.ts | 35 ++++++++++++++++++- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/actions-languageserver/src/context-providers/secrets.ts b/actions-languageserver/src/context-providers/secrets.ts index 6cff0ce..7f735e0 100644 --- a/actions-languageserver/src/context-providers/secrets.ts +++ b/actions-languageserver/src/context-providers/secrets.ts @@ -41,6 +41,15 @@ export async function getSecrets( } >(); + secrets.orgSecrets.forEach(secret => + secretsMap.set(secret.value.toLowerCase(), { + key: secret.value, + value: new data.StringData("***"), + description: "Organization secret" + }) + ); + + // Override org secrets with repo secrets secrets.repoSecrets.forEach(secret => secretsMap.set(secret.value.toLowerCase(), { key: secret.value, @@ -76,6 +85,7 @@ async function getRemoteSecrets( ): Promise<{ repoSecrets: StringData[]; environmentSecrets: StringData[]; + orgSecrets: StringData[]; }> { return { repoSecrets: await cache.get(`${repo.owner}/${repo.name}/secrets`, undefined, () => @@ -86,7 +96,8 @@ async function getRemoteSecrets( (await cache.get(`${repo.owner}/${repo.name}/secrets/environment/${environmentName}`, undefined, () => fetchEnvironmentSecrets(octokit, repo.id, environmentName) ))) || - [] + [], + orgSecrets: await cache.get(`${repo.owner}/secrets`, undefined, () => fetchOrganizationSecrets(octokit, repo)) }; } @@ -129,3 +140,18 @@ async function fetchEnvironmentSecrets( return []; } + +async function fetchOrganizationSecrets(octokit: Octokit, repo: RepositoryContext): Promise { + try { + const secrets: {name: string}[] = await octokit.paginate("GET /repos/{owner}/{repo}/actions/organization-secrets", { + owner: repo.owner, + repo: repo.name, + per_page: 100 + }); + return secrets.map(secret => new StringData(secret.name)); + } catch (e) { + console.log("Failure to retrieve organization secrets: ", e); + } + + return []; +} diff --git a/actions-languageserver/src/context-providers/variables.ts b/actions-languageserver/src/context-providers/variables.ts index bde04b7..eb150ec 100644 --- a/actions-languageserver/src/context-providers/variables.ts +++ b/actions-languageserver/src/context-providers/variables.ts @@ -42,6 +42,15 @@ export async function getVariables( } >(); + variables.organizationVariables.forEach(variable => + variablesMap.set(variable.key.toLowerCase(), { + key: variable.key, + value: new data.StringData(variable.value.coerceString()), + description: `${variable.value.coerceString()} - Organization variable` + }) + ); + + // Override org variables with repo variables variables.repoVariables.forEach(variable => variablesMap.set(variable.key.toLowerCase(), { key: variable.key, @@ -77,6 +86,7 @@ export async function getRemoteVariables( ): Promise<{ repoVariables: Pair[]; environmentVariables: Pair[]; + organizationVariables: Pair[]; }> { // Repo variables return { @@ -88,7 +98,10 @@ export async function getRemoteVariables( (await cache.get(`${repo.owner}/${repo.name}/vars/environment/${environmentName}`, undefined, () => fetchEnvironmentVariables(octokit, repo.id, environmentName) ))) || - [] + [], + organizationVariables: await cache.get(`${repo.owner}/vars`, undefined, () => + fetchOrganizationVariables(octokit, repo) + ) }; } @@ -137,3 +150,23 @@ async function fetchEnvironmentVariables( return []; } + +async function fetchOrganizationVariables(octokit: Octokit, repo: RepositoryContext): Promise { + try { + const variables: {name: string; value: string}[] = await octokit.paginate( + "GET /repos/{owner}/{repo}/actions/organization-variables", + { + owner: repo.owner, + repo: repo.name, + per_page: 100 + } + ); + return variables.map(variable => { + return {key: variable.name, value: new StringData(variable.value)}; + }); + } catch (e) { + console.log("Failure to retrieve organization variables: ", e); + } + + return []; +} From dc2ada05a70a94b6d537c13e4dafff9788a7c362 Mon Sep 17 00:00:00 2001 From: Josh Gross Date: Mon, 30 Jan 2023 19:05:34 -0500 Subject: [PATCH 2/2] Skip fetching org values for non-org repos --- actions-languageserver/src/context-providers/secrets.ts | 4 ++++ actions-languageserver/src/context-providers/variables.ts | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/actions-languageserver/src/context-providers/secrets.ts b/actions-languageserver/src/context-providers/secrets.ts index 7f735e0..61c6ca0 100644 --- a/actions-languageserver/src/context-providers/secrets.ts +++ b/actions-languageserver/src/context-providers/secrets.ts @@ -142,6 +142,10 @@ async function fetchEnvironmentSecrets( } async function fetchOrganizationSecrets(octokit: Octokit, repo: RepositoryContext): Promise { + if (!repo.organizationOwned) { + return []; + } + try { const secrets: {name: string}[] = await octokit.paginate("GET /repos/{owner}/{repo}/actions/organization-secrets", { owner: repo.owner, diff --git a/actions-languageserver/src/context-providers/variables.ts b/actions-languageserver/src/context-providers/variables.ts index eb150ec..52babbd 100644 --- a/actions-languageserver/src/context-providers/variables.ts +++ b/actions-languageserver/src/context-providers/variables.ts @@ -152,6 +152,10 @@ async function fetchEnvironmentVariables( } async function fetchOrganizationVariables(octokit: Octokit, repo: RepositoryContext): Promise { + if (!repo.organizationOwned) { + return []; + } + try { const variables: {name: string; value: string}[] = await octokit.paginate( "GET /repos/{owner}/{repo}/actions/organization-variables",