diff --git a/actions-languageserver/src/context-providers.ts b/actions-languageserver/src/context-providers.ts index 8d37724..2263ff3 100644 --- a/actions-languageserver/src/context-providers.ts +++ b/actions-languageserver/src/context-providers.ts @@ -1,6 +1,7 @@ import {data} from "@github/actions-expressions"; import {ContextProviderConfig} from "@github/actions-languageservice"; import {WorkflowContext} from "@github/actions-languageservice/context/workflow-context"; +import {isMapping, isString} from "@github/actions-workflow-parser"; import {Octokit} from "@octokit/rest"; import {getSecrets} from "./context-providers/secrets"; import {getStepsContext} from "./context-providers/steps"; @@ -27,7 +28,23 @@ export function contextProviders( ) => { switch (name) { case "secrets": { - const secrets = await getSecrets(octokit, cache, repo.owner, repo.name); + let environmentName: string | undefined; + if (workflowContext?.job?.environment) { + if (isString(workflowContext.job.environment)) { + environmentName = workflowContext.job.environment.value; + } else if (isMapping(workflowContext.job.environment)) { + for (const x of workflowContext.job.environment) { + if (isString(x.key) && x.key.value === "name") { + if (isString(x.value)) { + environmentName = x.value.value; + } + break; + } + } + } + } + + const secrets = await getSecrets(octokit, cache, repo, environmentName); defaultContext = defaultContext || new data.Dictionary(); secrets.forEach(secret => defaultContext!.add(secret.value, new data.StringData("***"))); diff --git a/actions-languageserver/src/context-providers/secrets.ts b/actions-languageserver/src/context-providers/secrets.ts index afdb2e7..c9ca049 100644 --- a/actions-languageserver/src/context-providers/secrets.ts +++ b/actions-languageserver/src/context-providers/secrets.ts @@ -1,16 +1,35 @@ import {StringData} from "@github/actions-expressions/data/string"; import {Octokit} from "@octokit/rest"; +import {RepositoryContext} from "../initializationOptions"; import {TTLCache} from "../utils/cache"; export async function getSecrets( octokit: Octokit, cache: TTLCache, - owner: string, - name: string + repo: RepositoryContext, + environmentName?: string ): Promise { - const repoSecrets = await cache.get(`${owner}/${name}/secrets`, undefined, () => fetchSecrets(octokit, owner, name)); + const secrets: StringData[] = []; - return repoSecrets; + // Repo secrets + const repoSecrets = await cache.get(`${repo.owner}/${repo.name}/secrets`, undefined, () => + fetchSecrets(octokit, repo.owner, repo.name) + ); + + secrets.push(...repoSecrets); + + // Environment secrets + if (environmentName) { + const envSecrets = await cache.get( + `${repo.owner}/${repo.name}/secrets/environment/${environmentName}`, + undefined, + () => fetchEnvironmentSecrets(octokit, repo.id, environmentName) + ); + + secrets.push(...envSecrets); + } + + return secrets.sort(); } async function fetchSecrets(octokit: Octokit, owner: string, name: string): Promise { @@ -27,3 +46,22 @@ async function fetchSecrets(octokit: Octokit, owner: string, name: string): Prom return []; } + +async function fetchEnvironmentSecrets( + octokit: Octokit, + repositoryId: number, + environmentName: string +): Promise { + try { + const response = await octokit.actions.listEnvironmentSecrets({ + repository_id: repositoryId, + environment_name: environmentName + }); + + return response.data.secrets.map(secret => new StringData(secret.name)); + } catch (e) { + console.log("Failure to retrieve environment secrets: ", e); + } + + return []; +}