Skip to content

Conversation

@robertbrignull
Copy link
Contributor

This change started out just trying to add --search-path to the CodeQL args when resolving queries, however in doing that I wasn't able to get the data where I needed it nicely. A simpler but cruder answer could have been to stuff some extra fields in the objects already being passed around, but that didn't seem ideal to me. Instead this PR restructures how we parse and process the config considerably to move everything sooner and to one place.

The main changes are:

  • All config parsing and subsequent processing happens in the init action. Previously it was mostly in the init action, but there was a large chunk in the analyze action where we checked out external repositories and converted the user-supplied list of queries and query suites to run into an explicit list of query files.
  • The data stored in the internal config file that persists between actions has changed. Some extra data has been added like the list of languages. Some data has changed format, such as the set of queries which is now an explicit array of filepaths to existing ql files.

This is quite a big change, but I think is has a few benefits:

  • The user gets notified of problems sooner, because we validate everything in the init action. Previously if you specified queries from a remote repository but the repository or file path didn't exist, then you wouldn't find out until after the code has been built.
  • All config parsing is done in one place. I hope this makes it easier to us to understand and develop. It also makes it easier to do features like adding the CodeQL --search-path because all of the data is available.
  • By storing more data and more explicit data in the internal config file, and treating the data as immutable, it makes the other actions simpler.

Merge / deployment checklist

  • Confirm this change is backwards compatible with existing workflows.
  • Confirm the readme has been updated if necessary.

Copy link
Contributor

@sampart sampart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a really great improvement. All my comments are stylistic, so I'm approving this. Thank you!

src/codeql.ts Outdated
}

/**
* Stores the CodeQL object, and is populated by `setupCodeQL`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might also be set by getCodeQL; I don't know if you need to mention that.

return partialCodeql[methodName];
}

export function setCodeQL(partialCodeql: Partial<CodeQL>) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need a comment saying "Only for use in tests?"

/**
* Get the file path where the parsed config will be stored.
*/
export function getParsedConfigFile(): string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getParsedConfigFile sounds to me like you're returning the configuration itself. What about getPathToParsedConfigFile?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you do this, I guess the previous method should be renamed to something like getPathToParsedConfigFileFolder, although that does sound a bit clunky.

return languages;
}

export async function getBlankConfig(): Promise<Config> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this be better as getDefaultConfig, since it does have content? That would also bring parity with addDefaultQueries.


// And the contents should parse correctly to the config that was returned
t.deepEqual(fs.readFileSync(configFile, 'utf8'), JSON.stringify(config));
// And the same config should be returned again
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"again" makes it sound like you're calling this function for the second time, but you're not

Suggested change
// And the same config should be returned again
// And that same newly-initialised config should now be returned by getConfig

queryUses: string) {

// The logic for parsing the string is based on what actions does for
// parsing the 'uses' actions in the workflow file
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this comment relate just to the 4 lines that follow? If not, I'd put it in the function-level comment.


// Property names from the user-supplied config file.
const NAME_PROPERTY = 'name';
const DISPLAY_DEFAULT_QUERIES_PROPERTY = 'disable-default-queries';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this wasn't added in this PR, but you're making use of it in your changed code, and that code would be much easier to read if it was called DISABLE_DEFAULT_QUERIES_PROPERTY.

Consider this bit, for example:

if (!parsedYAML[DISPLAY_DEFAULT_QUERIES_PROPERTY]) {
  await addDefaultQueries(languages, queries);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for spotting that. I think that must just be a slip of the keyboard from when that property was originally added.

* a default config. The parsed config is then stored to a known location.
*/
export async function initConfig(): Promise<Config> {
let configFile = core.getInput('config-file');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let configFile = core.getInput('config-file');
const configFile = core.getInput('config-file');

await externalQueries.checkoutExternalQueries(config);
await externalQueries.checkoutExternalRepository("github/codeql-go", "df4c6869212341b601005567381944ed90906b6b");

// COPYRIGHT file existed in df4c6869212341b601005567381944ed90906b6b but not in master
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// COPYRIGHT file existed in df4c6869212341b601005567381944ed90906b6b but not in master
// COPYRIGHT file existed in df4c6869212341b601005567381944ed90906b6b but not in main

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default branch on https://github.com/github/codeql-go is still called master. I'll make the comment more clear that it's talking about the default branch without naming it.


export async function checkoutExternalQueries(config: configUtils.Config) {
/**
* Checkout a repository at the given ref, and return the directory of the checkout.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Checkout a repository at the given ref, and return the directory of the checkout.
* Check out repository at the given ref, and return the directory of the checkout.

Removing the "a" makes it clearer how you're using the repository parameter.

@robertbrignull robertbrignull merged commit b673c57 into main Jul 16, 2020
@robertbrignull robertbrignull deleted the codeql_search_path branch July 16, 2020 08:17
@github-actions github-actions bot mentioned this pull request Jul 20, 2020
@github-actions github-actions bot mentioned this pull request Jul 27, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants