Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fetching variables isn't handling 404 error requests for Variables in GHES versions before 3.8 #71

Open
1 of 4 tasks
planetsLightningArrester opened this issue Apr 11, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@planetsLightningArrester

Describe the bug
Whenever I open a workflow connected to GHES 3.7, I get the following error message (sensitive data hidden by ***). This is because the Variables support was introduced on GHES 3.8.

Failure to retrieve variables:  Cs [HttpError]: Not Found
{
  status: 404,
  response: {
    url: 'https://***/api/v3/repos/***/***/actions/variables?per_page=100',
    status: 404,
    headers: {
      'access-control-allow-origin': '*',
      'access-control-expose-headers': 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset',
      'content-encoding': 'gzip',
      'content-security-policy': "default-src 'none'",
      'content-type': 'application/json; charset=utf-8',
      date: 'Wed, 10 Apr 2024 16:41:09 GMT',
      'referrer-policy': 'origin-when-cross-origin, strict-origin-when-cross-origin',
      server: 'GitHub.com',
      'strict-transport-security': 'max-age=31536000; includeSubdomains',
      'transfer-encoding': 'chunked',
      'x-accepted-oauth-scopes': 'repo',
      'x-content-type-options': 'nosniff',
      'x-frame-options': 'deny',
      'x-github-enterprise-version': '3.7.5',
      'x-github-media-type': 'github.v3; format=json',
      'x-github-request-id': '***',
      'x-oauth-client-id': '***',
      'x-oauth-scopes': 'repo, workflow',
      'x-ratelimit-limit': '5000',
      'x-ratelimit-remaining': '4982',
      'x-ratelimit-reset': '1712767559',
      'x-ratelimit-resource': 'core',
      'x-ratelimit-used': '18',
      'x-runtime-rack': '0.033786',
      'x-xss-protection': '0'
    },
    data: {
      message: 'Not Found',
      documentation_url: 'https://docs.github.com/[email protected]/rest'
    }
  },
  request: {
    method: 'GET',
    url: 'https://***/api/v3/repos/***/***/actions/variables?per_page=100',
    headers: {
      accept: 'application/vnd.github.v3+json',
      'user-agent': 'VS Code GitHub Actions (0.26.2) octokit-rest.js/19.0.7 octokit-core.js/4.1.0 Node.js/18.18.2 (linux; x64)',
      authorization: 'token [REDACTED]'
    },
    request: { hook: [Function: bound bound e] }
  }
}

To Reproduce
Steps to reproduce the behavior:

  1. Log into a GitHub Enterprise server version 3.7 in VSCode
  2. Open a workflow file related to a GH project
  3. See several 404 errors trying to reach https://<ghes_url>/api/v3/repos/<user>/<repo>/actions/variables

Expected behavior
Either detect whether the server supports this request or waive this error without throwing it considering that the server may not support this.

Screenshots
If applicable, add screenshots to help explain your problem.

Package/Area

  • Expressions
  • Workflow Parser
  • Language Service
  • Language Server

Package Version
v0.3.9

Additional context
I recently reported github/vscode-github-actions#313. I noticed their repo uses @actions/languageserver, and after some investigation, I found that the root cause for unhandled 404 error requests for Variables might be related to the code below - based on the error message I'm getting (line 142).

async function fetchVariables(octokit: Octokit, owner: string, name: string): Promise<Pair[]> {
try {
return await octokit.paginate(
octokit.actions.listRepoVariables,
{
owner: owner,
repo: name,
per_page: 100
},
response =>
response.data.map(variable => {
return {key: variable.name, value: new StringData(variable.value)};
})
);
} catch (e) {
console.log("Failure to retrieve variables: ", e);
throw e;
}
}

The only place I can see this function being called is inside getRemoteVariables, which is also only used in the code below (line 47).

try {
const variables = await getRemoteVariables(octokit, cache, repo, environmentName);
// Build combined map of variables
const variablesMap = new Map<
string,
{
key: string;
value: data.StringData;
description?: string;
}
>();
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,
value: new data.StringData(variable.value.coerceString()),
description: `${variable.value.coerceString()} - Repository variable`
})
);
// Override repo variables with environment veriables (if defined)
variables.environmentVariables.forEach(variable =>
variablesMap.set(variable.key.toLowerCase(), {
key: variable.key,
value: new data.StringData(variable.value.coerceString()),
description: `${variable.value.coerceString()} - Variable for environment \`${environmentName || ""}\``
})
);
// Sort variables by key and add to context
Array.from(variablesMap.values())
.sort((a, b) => a.key.localeCompare(b.key))
.forEach(variable => variablesContext?.add(variable.key, variable.value, variable.description));
return variablesContext;
} catch (e) {
if (!(e instanceof RequestError)) throw e;
if (e.name == "HttpError" && e.status == 404) {
log("Failure to request variables. Ignore if you're using GitHub Enterprise Server below version 3.8");
return variablesContext;
} else throw e;
}

However, the error should be caught by:

} catch (e) {
if (!(e instanceof RequestError)) throw e;
if (e.name == "HttpError" && e.status == 404) {
log("Failure to request variables. Ignore if you're using GitHub Enterprise Server below version 3.8");
return variablesContext;
} else throw e;
}

And the error would be waived. But it looks like the error isn't handled properly for e.name == "HttpError" && e.status == 404 and the error is thrown anyway.

Blaming the file, I see 41436c6 might have shadowed the case where the context is still returned and a log message is displayed. I'm not 100% confident of this because I don't know if the error thrown for 404 is NOT a RequestError, but that's the only reason I could think of.

Thanks for the language server :) amazing work here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant