diff --git a/.github/auto-assign-config.yml b/.github/auto-assign-config.yml new file mode 100644 index 0000000..b3d46a4 --- /dev/null +++ b/.github/auto-assign-config.yml @@ -0,0 +1,26 @@ +# Set to true to add reviewers to pull requests +addReviewers: true + +# Set to true to add assignees to pull requests +addAssignees: author + +# A list of reviewers to be added to pull requests (GitHub user name) +reviewers: + - iamwatchdogs + +# A number of reviewers added to the pull request +# Set 0 to add all the reviewers (default: 0) +numberOfReviewers: 1 + +# A list of assignees, overrides reviewers if set +# assignees: +# - assigneeA + +# A number of assignees to add to the pull request +# Set to 0 to add all of the assignees. +# Uses numberOfReviewers if unset. +# numberOfAssignees: 2 + +# A list of keywords to be skipped the process that add reviewers if pull requests include it +# skipKeywords: +# - wip \ No newline at end of file diff --git a/.github/scripts/convert_to_html_tables.py b/.github/scripts/convert_to_html_tables.py index 63ac4fa..1b8b014 100644 --- a/.github/scripts/convert_to_html_tables.py +++ b/.github/scripts/convert_to_html_tables.py @@ -11,7 +11,26 @@ > GitHub action variable: ${{ github.repository }} ''' + def find_table_points(lines): + """ + Find table points within a given list of lines. + + The table points are determined by the presence of the markers: + + + + Args: + lines (list): List of lines to search in. + + Returns: + tuple: A tuple of two integers containing the start and end indices of + the table points. + + Raises: + SystemExit: If the table markers are not found or if the table end + marker appears before the table start marker. + """ # Setting default return values table_start = None @@ -42,6 +61,18 @@ def find_table_points(lines): def main(): + """ + Update the index.md file with the latest contributors data. + + This function retrieves the REPO_NAME environment variable and the + CONTRIBUTORS_LOG file path. It then reads the log file and extracts the + data from it. The function then reads the index.md file and calculates + the table points. If the table does not exist, it creates the table + header. The function then iterates over the log data and updates the + table with the latest data. Finally, it updates the index.md file with + the updated data and prints a success message. + + """ # Retrieving Environmental variables REPO_NAME = os.environ.get('REPO_NAME') @@ -79,12 +110,14 @@ def main(): # Processing contributors-names contributors_names = details['contributor-name'] - contributors_names_list = [f'{name}' for name in contributors_names] + contributors_names_list = [ + f'{name}' for name in contributors_names] contributors_names_output = ', '.join(contributors_names_list) # Processing pull-requests pull_requests = details['pull-request-number'] - pull_requests_list = [f'{pr}' for pr in pull_requests] + pull_requests_list = [ + f'{pr}' for pr in pull_requests] pull_requests_output = ', '.join(pull_requests_list) # Processing demo-path @@ -94,6 +127,12 @@ def main(): demo_path_output = f'/{REPO_NAME}/{title}/' if title == 'root' or title == '{init}': demo_path_output = f'/{REPO_NAME}/' + elif title == '{workflows}': + demo_path_output = f'/{REPO_NAME}/.github/workflows' + elif title == '{scripts}': + demo_path_output = f'/{REPO_NAME}/.github/scripts' + elif title == '{others}': + demo_path_output = f'/{REPO_NAME}/.github' # Appending all data together updated_lines.append('\t\n') diff --git a/.github/scripts/update_contributors_log.py b/.github/scripts/update_contributors_log.py index 5e4d056..01bba0a 100644 --- a/.github/scripts/update_contributors_log.py +++ b/.github/scripts/update_contributors_log.py @@ -15,7 +15,21 @@ > GitHub action variable: ${{ github.event.pull_request.number }} ''' + def get_project_title(pr_data): + """ + Determines the project title based on the file paths in the pull request data. + + Args: + pr_data (dict): The pull request data containing file paths. + + Returns: + str: The project title derived from the directory name in the file path. + Returns 'root' if changes are made in the root of the repository. + Special cases include '{workflows}', '{scripts}', and '{others}' + for certain paths within the '.github' directory. + + """ # Setting default value project_title = 'root' @@ -26,16 +40,45 @@ def get_project_title(pr_data): project_title = i["path"] break - # If we find a directory - if project_title != 'root': - project_title = project_title.split('/')[0] + # changes are made in the root of repo + if project_title == 'root': + return project_title + + if '.github/workflows' in project_title: + project_title = '{workflows}' + elif '.github/scripts' in project_title: + project_title = '{scripts}' + elif '.github' in project_title: + project_title = '{others}' + else: + project_title = project_title.split('/')[0] # directory name return project_title + def get_contributor_name(pr_data): + """ + Retrieves the username of the contributor who made the pull request. + + Args: + pr_data (dict): The pull request data containing the author's username. + + Returns: + str: The username of the contributor. + """ return pr_data["author"]["login"] + def get_demo_path(pr_data): + """ + Retrieves the demo path for the pull request. + + Args: + pr_data (dict): The pull request data containing information about the pull request. + + Returns: + str: The demo path of the pull request. + """ # Getting required values REPO_NAME = os.environ.get('REPO_NAME') @@ -45,8 +88,17 @@ def get_demo_path(pr_data): if PROJECT_NAME == 'root': return f'https://github.com/{REPO_NAME}/' + url_path = PROJECT_NAME + + # Setting custom path for workflow maintance + SPECIAL_CASES = ['{workflows}', '{scripts}', '{others}'] + if PROJECT_NAME in SPECIAL_CASES: + url_path = '.github' + if PROJECT_NAME in SPECIAL_CASES[:2]: + url_path += f'/{PROJECT_NAME[1:-1]}' + # Setting default value - demo_path = f'https://github.com/{REPO_NAME}/tree/main/{PROJECT_NAME}' + demo_path = f'https://github.com/{REPO_NAME}/tree/main/{url_path}' found_required_path = False # Iterating through the "files" list @@ -56,7 +108,7 @@ def get_demo_path(pr_data): demo_path = path found_required_path = True break - elif path.lower().endswith('index.md') or path.lower().endswith('readme.md'): + elif path.lower().endswith('index.md') or path.lower().endswith('readme.md'): demo_path = path found_required_path = True @@ -70,7 +122,26 @@ def get_demo_path(pr_data): return demo_path + def main(): + """ + Updates the contributors log file after a pull request has been merged. + + This function is to be called in a GitHub Actions workflow after a pull request has been merged. + It reads the details of the current pull request from a JSON file, extracts the required information, + and updates the contributors log file accordingly. + + The contributors log file is a JSON file that contains information about each contributor, including + their name, the number of the pull request they contributed to, and the path to their project. + + The function dumps the data into the log file and outputs a success message upon completion. + + Args: + None + + Returns: + None + """ # Setting required file paths CURRENT_PR_DETAILS_PATH = 'pr.json' @@ -125,5 +196,6 @@ def main(): # Output message print(f'Successfully {operation_name} the log file') + if __name__ == '__main__': main() diff --git a/.github/scripts/update_index_md.py b/.github/scripts/update_index_md.py index e5066d2..7095743 100644 --- a/.github/scripts/update_index_md.py +++ b/.github/scripts/update_index_md.py @@ -11,7 +11,26 @@ > GitHub action variable: ${{ github.repository }} ''' + def find_table_points(lines): + """ + Find table points within a given list of lines. + + The table points are determined by the presence of the markers: + + + + Args: + lines (list): List of lines to search in. + + Returns: + tuple: A tuple of two integers containing the start and end indices of + the table points. + + Raises: + SystemExit: If the table markers are not found or if the table end + marker appears before the table start marker. + """ # Setting default return values table_start = None @@ -42,6 +61,18 @@ def find_table_points(lines): def main(): + """ + Update the index.md file with the latest contributors data. + + This function retrieves the REPO_NAME environment variable and the + CONTRIBUTORS_LOG file path. It then reads the log file and extracts the + data from it. The function then reads the index.md file and calculates + the table points. If the table does not exist, it creates the table + header. The function then iterates over the log data and updates the + table with the latest data. Finally, it updates the index.md file with + the updated data and prints a success message. + + """ # Retrieving Environmental variables REPO_NAME = os.environ.get('REPO_NAME') @@ -64,7 +95,8 @@ def main(): # Creating table header if doesn't exist if table_end - table_start == 1: table_header = list() - table_header.append('| Project Title | Contributor Names | Pull Requests | Demo |\n') + table_header.append( + '| Project Title | Contributor Names | Pull Requests | Demo |\n') table_header.append('| --- | --- | --- | --- |\n') lines[table_start+1:table_end] = table_header @@ -76,12 +108,14 @@ def main(): # Processing contributors-names contributors_names = details['contributor-name'] - contributors_names_list = [f'[{name}](https://github.com/{name} "goto {name} profile")' for name in contributors_names] + contributors_names_list = [ + f'[{name}](https://github.com/{name} "goto {name} profile")' for name in contributors_names] contributors_names_output = ', '.join(contributors_names_list) # Processing pull-requests pull_requests = details['pull-request-number'] - pull_requests_list = [f'[#{pr}](https://github.com/{REPO_NAME}/pull/{pr} "visit pr \#{pr}")' for pr in pull_requests] + pull_requests_list = [ + f'[#{pr}](https://github.com/{REPO_NAME}/pull/{pr} "visit pr \#{pr}")' for pr in pull_requests] pull_requests_output = ', '.join(pull_requests_list) # Processing demo-path @@ -91,9 +125,16 @@ def main(): demo_path_output = f'[/{REPO_NAME}/{title}/]({demo_path} "view the result of {title}")' if title == 'root' or title == '{init}': demo_path_output = f'[/{REPO_NAME}/]({demo_path} "view the result of {title}")' + elif title == '{workflows}': + demo_path_output = f'[/{REPO_NAME}/.github/workflows]({demo_path} "view the result of {title}")' + elif title == '{scripts}': + demo_path_output = f'[/{REPO_NAME}/.github/scripts]({demo_path} "view the result of {title}")' + elif title == '{others}': + demo_path_output = f'[/{REPO_NAME}/.github]({demo_path} "view the result of {title}")' # Appending all data together - updated_lines.append(f'| {title} | {contributors_names_output} | {pull_requests_output} | {demo_path_output} |\n') + updated_lines.append( + f'| {title} | {contributors_names_output} | {pull_requests_output} | {demo_path_output} |\n') # Updating the lines with updated data lines[table_start+3:table_end] = updated_lines diff --git a/.github/workflows/auto-assigner.yml b/.github/workflows/auto-assigner.yml new file mode 100644 index 0000000..cc28ae9 --- /dev/null +++ b/.github/workflows/auto-assigner.yml @@ -0,0 +1,19 @@ +name: Auto Assign + +on: + pull_request_target: + types: [opened, ready_for_review] + issues: + types: [opened] + +permissions: + issues: write + pull-requests: write + +jobs: + auto-assign: + runs-on: ubuntu-latest + steps: + - uses: kentaro-m/auto-assign-action@v1.2.5 + with: + configuration-path: '.github/auto-assign-config.yml' \ No newline at end of file diff --git a/.github/workflows/auto-commenter.yml b/.github/workflows/auto-commenter.yml new file mode 100644 index 0000000..b35a90b --- /dev/null +++ b/.github/workflows/auto-commenter.yml @@ -0,0 +1,28 @@ +name: Auto-commenter + +on: + pull_request_target: + types: [opened, closed] + +permissions: + id-token: write + issues: write + pull-requests: write + +jobs: + automated-message: + runs-on: ubuntu-latest + steps: + - uses: wow-actions/auto-comment@v1 + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + pullRequestOpened: | + 👋 @{{ author }} + Thank you for raising your pull request. + Please make sure you have followed our contributing guidelines. We will review it as soon as possible. + + pullRequestClosed: | + 👋 @{{ author }} This PR is closed. If you think there's been a mistake, please contact the maintainer @iamwatchdogs. + + pullRequestMerged: | + Thank you for contributing @{{ author }}. Make sure to check your contribution on [GitHub Pages](https://grow-with-open-source.github.io/Javascript-Projects/ "view contributions"). \ No newline at end of file diff --git a/.github/workflows/auto-labeler.yml b/.github/workflows/auto-labeler.yml new file mode 100644 index 0000000..bc68a4f --- /dev/null +++ b/.github/workflows/auto-labeler.yml @@ -0,0 +1,50 @@ +name: hacktoberfest-labeler + +on: + pull_request_target: + types: [opened, reopened, closed] + + +permissions: + contents: read + pull-requests: write + +jobs: + auto-labeler: + runs-on: ubuntu-latest + steps: + - name: Check for hacktoberfest season + id: check-month + run: | + current_month=$(date +'%m') + if [ "$current_month" == "10" ]; then + echo "is_october=true" >> $GITHUB_OUTPUT + else + echo "is_october=false" >> $GITHUB_OUTPUT + fi + + - name: Creating config file + env: + ACTION: ${{ github.event.action }} + run: | + touch ./hacktoberfest-labeler.yml + + if [ "$ACTION" != "closed" ]; then + echo "hacktoberfest:" > hacktoberfest-labeler.yml + else + echo "hacktoberfest-accepted:" > hacktoberfest-labeler.yml + fi + echo "- changed-files:" >> hacktoberfest-labeler.yml + echo " - any-glob-to-any-file: '**'" >> hacktoberfest-labeler.yml + + echo "Created the config file:" + echo "------------------------" + cat ./hacktoberfest-labeler.yml + + - name: Label the PRs + if: steps.check-month.outputs.is_october == 'true' || + github.event.pull_request.merged == 'true' && + contains(github.event.pull_request.labels.*.name, 'hacktoberfest') + uses: actions/labeler@v5.0.0 + with: + configuration-path: ./hacktoberfest-labeler.yml \ No newline at end of file diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000..fc66c4b --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,25 @@ +name: close-stale-issue-and-prs + +on: + schedule: + - cron: '30 1 * * *' + +permissions: + contents: write + issues: write + pull-requests: write + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v8 + with: + stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.' + stale-pr-message: 'This PR is stale because it has been open 45 days with no activity. Remove stale label or comment or this will be closed in 10 days.' + close-issue-message: 'This issue was closed because it has been stalled for 5 days with no activity.' + close-pr-message: 'This PR was closed because it has been stalled for 10 days with no activity.' + days-before-issue-stale: 30 + days-before-pr-stale: 45 + days-before-issue-close: 5 + days-before-pr-close: 10 \ No newline at end of file