Skip to content

Lint - Categories in the properties.json file - #1099

Closed
aparna-ravindra wants to merge 7 commits into
actions:mainfrom
aparna-ravindra:categories-lint
Closed

aparna-ravindra wants to merge 7 commits into
actions:mainfrom
aparna-ravindra:categories-lint

Conversation

@aparna-ravindra

Copy link
Copy Markdown
Contributor

Context

The categories listed in the .properties.json file of a template determine the section under which the template appears in the actions/new page.

What does this PR contain?

This PR aims at validating the categories field present in the .properties.json file for each of the templates and identifying that it contains at least one of the supported categories. The aim is to make the reviewer aware of such cases by commenting on the PR. The reviewer can then choose to recommend the right category for the template.

The list of recognised categories is maintained in the settings.json file and is shared in the comment with the PR owner.

This PR contains two workflows

  1. Checkout the PR branch and validate categories for all the templates. Save the result in a workflow artifact.
  2. Download the workflow artifact and comment on PR.

The comment on the PR appears like this: https://github.com/aparna-ravindra/starter-workflows/pull/42#issuecomment-920592073

tldr;
Two workflows were needed because the workflows running on the PR branch(from forked repo) do not have permission to comment on the issue. This has been documented here. In gist the doc says

combining pull_request_target workflow trigger with an explicit checkout of an untrusted PR is a dangerous practice that may lead to repository compromise.

At the same time it mentions:

If your workflow scenario simply requires commenting on the PR, but does not require a check out of the modified code, using pull_request_target is a logical shortcut.

Therefore the approach described in the doc has been followed.

@ashwinsangem ashwinsangem mentioned this pull request Sep 16, 2021
14 tasks done
@@ -0,0 +1,37 @@
require 'json'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why not use validate-data script itself?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The reasons I plan on keeping the script separate

  1. Modularity : The validate-data script already does multiple checks. We expect to add more checks in the validate-categories script, which will make validate-data bulky if combined.
  2. Validate-Data is a mandatory check on PR, failing which will block PR merge. We intend Validate-categories to nudge the PR author with information on best practices for the values of the category field. There is no plan on failing the check.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Ah! I think I get it now. category validation is an optional thing and we only put a PR message. Seems like we discussed it long back.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@aparna-ravindra actually just re-thinking about it, currently we are only validating the template type category and not tech stack category. And if so, then we should fail the validation just like validate-data. And hence we can make this part of validate-data itself. Thoughts?

@allowed_categories = settings['allowed_categories']

def validateCategories(categories)
return categories.nil? || (categories.is_a?(Array) && ! categories.select{|l| @allowed_categories.detect{|p| p.casecmp(l) == 0 } }.empty? )

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Will array intersection achieve same result as select and detect?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Need this to be case-insensitive

@allowed_categories = settings['allowed_categories']

def validateCategories(categories)
return categories.nil? || (categories.is_a?(Array) && ! categories.select{|l| @allowed_categories.detect{|p| p.casecmp(l) == 0 } }.empty? )

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

If categories is nil, then validate should fail

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

categories is an optional field. We do have a blank template today where there are no categories.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This seems troublesome to me. Blank is a special case we should handle is separately. For any other template, we can disallow missing categories.


result = []
for folder in folders
files = Dir.entries(folder).select {|entry| File.file?(File.join(folder, entry)) && (File.extname(entry) == ".yaml" || File.extname(entry) == ".yml") }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Do we need to co-relate with workflow yml file? Or just simply look through all properties file?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The co-relation is taken care by the validate-data script.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No, I meant why do we need to first find the workflow file name and then look for properties.json for that? We can directly iterate through all properties.json and validate category.

# read-only repo token
# no access to secrets
on:
pull_request:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

add on push event as well. ghes branch has direct pushes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ghes branch is updated only through the sync-ghes workflow, I believe.
Also, we require a PR to comment if needed. Otherwise, the validation script is run, but the result is not shared anywhere.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Got it. So, essentially master branch is the gatekeeper for ensuring correct categories.

@@ -0,0 +1,62 @@
name: Validate Categories on PR

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Please add a comment on what are the valid categories

- name: Save Validation Output
if: ${{steps.comment-format.outputs.content && steps.comment-format.outputs.content != '' }}
run: |
mkdir -p ./category_validation

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This approach for publishing artifact is needed due to the reason that PR workflow won't have permission to write to PR in case of forked repos most probably. Isn't it?
Would it be easier to write a bot or as I mentioned in another comment to make category validation part of validate-data

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.

2 participants