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 e1976c0..6bad0ea 100644 --- a/.github/scripts/convert_to_html_tables.py +++ b/.github/scripts/convert_to_html_tables.py @@ -21,6 +21,18 @@ class UpdateFileContent: REPO_NAME = None def __init__(self, FILE_PATH, condition=None): + """ + Constructor method of UpdateFileContent class. + + Parameters + ---------- + FILE_PATH : str + Path of the file to be updated. + condition : callable, optional + Condition to filter the contributors based on. + Defaults to None, which means no filtering. + + """ # Displaying starting Message print(f'\n--- Updating {FILE_PATH} ---\n') @@ -40,6 +52,14 @@ def __init__(self, FILE_PATH, condition=None): def get_lines(self): + """ + Reads the lines from the file located at `self.FILE_PATH`. + + Returns + ------- + list + List of lines read from the file. + """ # Reading lines from the file with open(self.FILE_PATH, 'r') as file: @@ -48,6 +68,17 @@ def get_lines(self): return lines def write_lines_into_file(self): + """ + Writes the lines to the file located at `self.FILE_PATH`. + + Parameters + ---------- + None + + Returns + ------- + None + """ # Updating the target file with open(self.FILE_PATH, 'w') as file: @@ -57,6 +88,23 @@ def write_lines_into_file(self): print(f"Updated '{self.FILE_PATH}' Successfully") def find_table_points(self, search_type): + """ + Finds the starting and ending points of a table in the file located at + `self.FILE_PATH` based on the `search_type`. + + Parameters + ---------- + search_type : str + Valid values are 'contributors' and 'table-of-content'. + + Returns + ------- + tuple + A tuple of `(table_starting_point, table_ending_point)` where + `table_starting_point` is the index of the line where the table + starts and `table_ending_point` is the index of the line where the + table ends. + """ # Setting default return values table_starting_point = None @@ -97,6 +145,16 @@ def find_table_points(self, search_type): return (table_starting_point, table_ending_point) def update_table_of_contributors(self, condition): + """ + Update the table of contributors based on the condition. + + Parameters + ---------- + condition : callable + A function that takes one argument (i.e., the core contribution) + and returns True if the contribution should be included in the table, or + False otherwise. If None, then all core contributions are included. + """ # Calculating stating and ending points of the targeted table table_of_contributors_start, table_of_contributors_end = self.find_table_points('contributors') @@ -135,7 +193,7 @@ def update_table_of_contributors(self, condition): # Processing core contribution core_contribution = details['core'] if condition is None: - core_contribution_output = f'{core_contribution}' + core_contribution_output = f'{core_contribution}' if core_contribution != 'Repo' else core_contribution # Processing pull-requests pull_requests = details['pull-request-number'] @@ -150,6 +208,12 @@ def update_table_of_contributors(self, condition): demo_path_output = f'./{core_contribution}/{specificity}' if title == 'root' or title == '{init}': demo_path_output = f'/{self.REPO_NAME}/' + elif title == '{workflows}': + demo_path_output = f'/{self.REPO_NAME}/.github/workflows' + elif title == '{scripts}': + demo_path_output = f'/{self.REPO_NAME}/.github/scripts' + elif title == '{others}': + demo_path_output = f'/{self.REPO_NAME}/.github/others' # Appending all data together updated_lines.append('\t\n') @@ -184,6 +248,22 @@ def update_table_of_contributors(self, condition): print('Successfully updated the contributor details !!!...') def update_table_of_content(self, condition): + """ + Update the table of content in the markdown file based on the specified condition. + + Args: + condition (callable): A function that takes one argument (i.e., the core contribution) + and returns True if the contribution should be included in the table, or + False otherwise. If None, then all core contributions are included. + + The method calculates the starting and ending points of the targeted table and + initializes necessary variables to store the table of content. It processes the + data from `self.DATA` to extract and organize the content by core and specificity. + The extracted data is sorted and used to update the markdown file with a structured + list of links representing the table of content. The links are formatted based on + whether a condition is given. Finally, the method updates the markdown lines and + prints a success message upon completion. + """ # Calculating stating and ending points of the targeted table table_of_content_start, table_of_content_end = self.find_table_points('table-of-content') @@ -248,6 +328,15 @@ def update_table_of_content(self, condition): def main(): + """ + The main function of the script is responsible for updating the root index file and the index files of `Theory` and `Solved-Problems` directories. + + The function takes in environment variables `REPO_NAME` and uses it to fetch the required data from the contributors log file. + + The function then updates the root index file and the index files of `Theory` and `Solved-Problems` directories using the fetched data. + + The function also prints out a success message at the end. + """ # Retrieving Environmental variables REPO_NAME = os.environ.get('REPO_NAME') diff --git a/.github/scripts/update_contributors_log.py b/.github/scripts/update_contributors_log.py index 2fb45f8..7b2c001 100644 --- a/.github/scripts/update_contributors_log.py +++ b/.github/scripts/update_contributors_log.py @@ -15,127 +15,215 @@ > GitHub action variable: ${{ github.event.pull_request.number }} ''' + def get_contribution_title(CURRENT_PR): - - # Setting default value - contribution_title = 'root' - path = contribution_title + """ + This function extracts the contribution title from the provided current pull request. + + Parameters: + - CURRENT_PR (dict): The current pull request information. + + Returns: + tuple: A tuple containing the contribution title and the path. + """ + + # Setting default value + contribution_title = 'root' + path = contribution_title + + # Iterating through the "files" list + for files in CURRENT_PR["files"]: + if '/' in files["path"]: + contribution_title = files["path"] + path = contribution_title + break + + if contribution_title == 'root': + return (contribution_title, path) + + if '.github/workflows' in path: + contribution_title = '{workflows}' + elif '.github/scripts' in path: + contribution_title = '{scripts}' + elif '.github' in path: + contribution_title = '{others}' + else: + splitted_title = contribution_title.split('/') + contribution_title = splitted_title[-2] if '.' in contribution_title else splitted_title[-1] + + return (contribution_title, path) + - # Iterating through the "files" list - for files in CURRENT_PR["files"]: - if '/' in files["path"]: - contribution_title = files["path"] - path = contribution_title - break +def get_contributor_name(CURRENT_PR): + """ + This function extracts the contributor name from the provided current pull request. - # If we find a directory - if contribution_title != 'root': - splitted_title = contribution_title.split('/') - contribution_title = splitted_title[-2] if '.' in contribution_title else splitted_title[-1] + Parameters: + - CURRENT_PR (dict): The current pull request information. - return (contribution_title, path) + Returns: + str: The contributor name. + """ + return CURRENT_PR["author"]["login"] -def get_contributor_name(CURRENT_PR): - return CURRENT_PR["author"]["login"] def get_core_type(CONTRIBUTION_TITLE, USED_PATH): - return USED_PATH.split('/')[0] if CONTRIBUTION_TITLE != 'root' else 'Repo' + """ + Determines the core type of the contribution based on the contribution title and used path. -def get_specificity(CONTRIBUTION_TITLE, USED_PATH): - return USED_PATH.split('/')[1] if CONTRIBUTION_TITLE != 'root' else 'Maintenance' + Parameters: + - CONTRIBUTION_TITLE (str): The title of the contribution, which can be a specific directory or a special identifier. + - USED_PATH (str): The file path associated with the contribution. -def get_demo_path(CURRENT_PR, CONTRIBUTION_TITLE, CORE_TYPE, SPECIFICITY): + Returns: + str: 'Repo' if the contribution title is one of the special identifiers ('root', '{workflows}', '{scripts}', '{others}'), + otherwise, the first segment of the used path is returned as the core type. + """ + if CONTRIBUTION_TITLE in ['root', '{workflows}', '{scripts}', '{others}']: + return 'Repo' + return USED_PATH.split('/')[0] - # Getting required values - REPO_NAME = os.environ.get('REPO_NAME') - # Handling a base case - if CONTRIBUTION_TITLE == 'root': - return f'https://github.com/{REPO_NAME}/' +def get_specificity(CONTRIBUTION_TITLE, USED_PATH): + """ + Determines the specificity of the contribution based on the contribution title and used path. - # Setting default value - demo_path = f'https://github.com/{REPO_NAME}/tree/main/{CORE_TYPE}/{SPECIFICITY}' - found_required_path = False + Parameters: + - CONTRIBUTION_TITLE (str): The title of the contribution, can be a specific directory or a special identifier. + - USED_PATH (str): The file path associated with the contribution. - # Iterating through the "files" list - for files in CURRENT_PR["files"]: - path = files["path"] - if "index.html" in path: - demo_path = path - found_required_path = True - break - elif path.lower().endswith('index.md') or path.lower().endswith('readme.md'): - demo_path = path - found_required_path = True + Returns: + str: The specificity of the contribution, extracted from the used path. + """ + if CONTRIBUTION_TITLE in ['root', '{workflows}', '{scripts}', '{others}']: + return 'Maintenance' + return USED_PATH.split('/')[1] - # Modifying demo path as a route - if found_required_path: - demo_path = '/'.join(demo_path.split('/')[:-1]) - # Checking out for spaces: - if ' ' in demo_path: - demo_path = '%20'.join(demo_path.split()) +def get_demo_path(CURRENT_PR, CONTRIBUTION_TITLE, CORE_TYPE, SPECIFICITY): + """ + Generates the demo path of the contribution based on the provided pull request information. + + Parameters: + - CURRENT_PR (dict): The current pull request information. + - CONTRIBUTION_TITLE (str): The title of the contribution. + - CORE_TYPE (str): The core type of the contribution. + - SPECIFICITY (str): The specificity of the contribution. + + Returns: + str: The generated demo path of the contribution. + """ + + # Getting required values + REPO_NAME = os.environ.get('REPO_NAME') + + # Handling a base cases + if CONTRIBUTION_TITLE == 'root': + return f'https://github.com/{REPO_NAME}/' + elif CONTRIBUTION_TITLE == '{workflow}': + return f'https://github.com/{REPO_NAME}/.github/workflows' + elif CONTRIBUTION_TITLE == '{scripts}': + return f'https://github.com/{REPO_NAME}/.github/scripts' + elif CONTRIBUTION_TITLE == '{others}': + return f'https://github.com/{REPO_NAME}/.github' + + # Setting default value + demo_path = f'https://github.com/{REPO_NAME}/tree/main/{CORE_TYPE}/{SPECIFICITY}' + found_required_path = False + + # Iterating through the "files" list + for files in CURRENT_PR["files"]: + path = files["path"] + if "index.html" in path: + demo_path = path + found_required_path = True + break + elif path.lower().endswith('index.md') or path.lower().endswith('readme.md'): + demo_path = path + found_required_path = True + + # Modifying demo path as a route + if found_required_path: + demo_path = '/'.join(demo_path.split('/')[:-1]) + + # Checking out for spaces: + if ' ' in demo_path: + demo_path = '%20'.join(demo_path.split()) + + return demo_path - return demo_path def main(): - + """ + The main function of the script is responsible for updating the contributors log file. + + The function takes in environment variables `REPO_NAME` and `PR_NUMBER` and uses it to fetch the required data from the current PR and the Contributors log file. + + The function then updates the Contributors log file either by appending a new entry or updating an existing one. + + The function also prints out a success message at the end. + """ + # Setting file paths - PR_DETAILS_FILE_PATH = 'pr.json' - CONTRIBUTION_LOG_FILE_PATH = '.github/data/contributors-log.json' - - # Reading contents from the current pr - with open(PR_DETAILS_FILE_PATH, 'r') as json_file: - CURRENT_PR = json.load(json_file) - - # Getting required value for update - CONTRIBUTION_TITLE, USED_PATH = get_contribution_title(CURRENT_PR) - CONTRIBUTOR_NAME = get_contributor_name(CURRENT_PR) - CORE_TYPE = get_core_type(CONTRIBUTION_TITLE, USED_PATH) - SPECIFICITY = get_specificity(CONTRIBUTION_TITLE, USED_PATH) - PR_NUMBER = os.environ.get('PR_NUMBER') - DEMO_PATH = get_demo_path(CURRENT_PR, CONTRIBUTION_TITLE, CORE_TYPE, SPECIFICITY) - - # Creating a new dict objects for JSON conversion - existing_data = None - new_data = { - CONTRIBUTION_TITLE: { - "contributor-name": [CONTRIBUTOR_NAME], - "core": CORE_TYPE, - "specificity": SPECIFICITY, - "pull-request-number": [PR_NUMBER], - "demo-path": DEMO_PATH - } - } - - # Processing the data dumps - operation_name = None - if os.path.exists(CONTRIBUTION_LOG_FILE_PATH): - - # Reading existing Log file - with open(CONTRIBUTION_LOG_FILE_PATH, 'r') as json_file: - existing_data = json.load(json_file) - - # performing updation or addition based on `PROJECT_TITLE` - if CONTRIBUTION_TITLE in existing_data: - if CONTRIBUTOR_NAME not in existing_data[CONTRIBUTION_TITLE]["contributor-name"]: - existing_data[CONTRIBUTION_TITLE]["contributor-name"].append(CONTRIBUTOR_NAME) - if PR_NUMBER not in existing_data[CONTRIBUTION_TITLE]["pull-request-number"]: - existing_data[CONTRIBUTION_TITLE]["pull-request-number"].append(PR_NUMBER) - operation_name = 'Updated' - else: - existing_data.update(new_data) - operation_name = 'Appended data to' - else: - existing_data = new_data - operation_name = 'Created' - - # Dumping the data into log file - with open(CONTRIBUTION_LOG_FILE_PATH, 'w') as json_file: - json.dump(existing_data, json_file, indent=2) - - # Output message - print(f'Successfully {operation_name} the log file') + PR_DETAILS_FILE_PATH = 'pr.json' + CONTRIBUTION_LOG_FILE_PATH = '.github/data/contributors-log.json' + + # Reading contents from the current pr + with open(PR_DETAILS_FILE_PATH, 'r') as json_file: + CURRENT_PR = json.load(json_file) + + # Getting required value for update + CONTRIBUTION_TITLE, USED_PATH = get_contribution_title(CURRENT_PR) + CONTRIBUTOR_NAME = get_contributor_name(CURRENT_PR) + CORE_TYPE = get_core_type(CONTRIBUTION_TITLE, USED_PATH) + SPECIFICITY = get_specificity(CONTRIBUTION_TITLE, USED_PATH) + PR_NUMBER = os.environ.get('PR_NUMBER') + DEMO_PATH = get_demo_path( + CURRENT_PR, CONTRIBUTION_TITLE, CORE_TYPE, SPECIFICITY) + + # Creating a new dict objects for JSON conversion + existing_data = None + new_data = { + CONTRIBUTION_TITLE: { + "contributor-name": [CONTRIBUTOR_NAME], + "core": CORE_TYPE, + "specificity": SPECIFICITY, + "pull-request-number": [PR_NUMBER], + "demo-path": DEMO_PATH + } + } + + # Processing the data dumps + operation_name = None + if os.path.exists(CONTRIBUTION_LOG_FILE_PATH): + + # Reading existing Log file + with open(CONTRIBUTION_LOG_FILE_PATH, 'r') as json_file: + existing_data = json.load(json_file) + + # performing updation or addition based on `PROJECT_TITLE` + if CONTRIBUTION_TITLE in existing_data: + if CONTRIBUTOR_NAME not in existing_data[CONTRIBUTION_TITLE]["contributor-name"]: + existing_data[CONTRIBUTION_TITLE]["contributor-name"].append( + CONTRIBUTOR_NAME) + if PR_NUMBER not in existing_data[CONTRIBUTION_TITLE]["pull-request-number"]: + existing_data[CONTRIBUTION_TITLE]["pull-request-number"].append( + PR_NUMBER) + operation_name = 'Updated' + else: + existing_data.update(new_data) + operation_name = 'Appended data to' + else: + existing_data = new_data + operation_name = 'Created' + + # Dumping the data into log file + with open(CONTRIBUTION_LOG_FILE_PATH, 'w') as json_file: + json.dump(existing_data, json_file, indent=2) + + # Output message + print(f'Successfully {operation_name} the log file') + if __name__ == '__main__': - main() \ No newline at end of file + main() diff --git a/.github/scripts/update_index_md.py b/.github/scripts/update_index_md.py index 10b2f20..2ea582c 100644 --- a/.github/scripts/update_index_md.py +++ b/.github/scripts/update_index_md.py @@ -21,6 +21,16 @@ class UpdateFileContent: REPO_NAME = None def __init__(self, FILE_PATH, condition=None): + """ + Initializes required variables and updates target file based on data. + + Updates the file located at `FILE_PATH` with contributor and content + tables. If `condition` is not `None`, it will be used to filter out + core contributions when updating the content table. + + :arg FILE_PATH: Path to the file to be updated. + :arg condition: Optional condition to filter out core contributions. + """ # Displaying starting Message print(f'\n--- Updating {FILE_PATH} ---\n') @@ -40,6 +50,11 @@ def __init__(self, FILE_PATH, condition=None): def get_lines(self): + """ + Reads lines from the file located at `self.FILE_PATH` and returns them. + + :return: List of lines read from the file. + """ # Reading lines from the file with open(self.FILE_PATH, 'r') as file: @@ -48,6 +63,12 @@ def get_lines(self): return lines def write_lines_into_file(self): + """ + Writes the lines in `self.lines` to the file located at `self.FILE_PATH` + and prints a success message. + + :return: None + """ # Updating the target file with open(self.FILE_PATH, 'w') as file: @@ -57,6 +78,17 @@ def write_lines_into_file(self): print(f"Updated '{self.FILE_PATH}' Successfully") def find_table_points(self, search_type): + """ + Finds the starting and ending points of a table in the file located at + `self.FILE_PATH` based on the `search_type`. + + :arg search_type: Type of table to search for. Valid values are + `contributors` and `table-of-content`. + :return: A tuple of `(table_starting_point, table_ending_point)` where + `table_starting_point` is the index of the line where the table + starts and `table_ending_point` is the index of the line where the + table ends. + """ # Setting default return values table_starting_point = None @@ -97,6 +129,14 @@ def find_table_points(self, search_type): return (table_starting_point, table_ending_point) def update_table_of_contributors(self, condition): + """ + Update the table of contributors based on the condition. + + Args: + condition (callable): A function that takes one argument (i.e., the core contribution) + and returns True if the contribution should be included in the table, or + False otherwise. If None, then all core contributions are included. + """ # Calculating stating and ending points of the targeted table table_of_contributors_start, table_of_contributors_end = self.find_table_points('contributors') @@ -133,7 +173,7 @@ def update_table_of_contributors(self, condition): # Processing core contribution core_contribution = details['core'] if condition is None: - core_contribution_output = f'[{core_contribution}]({core_contribution} "goto {core_contribution}")' + core_contribution_output = f'[{core_contribution}]({core_contribution} "goto {core_contribution}")' if core_contribution != 'Repo' else 'Repo' # Processing pull-requests pull_requests = details['pull-request-number'] @@ -148,6 +188,12 @@ def update_table_of_contributors(self, condition): demo_path_output = f'[./{core_contribution}/{specificity}/]({demo_path} "view the result of {title}")' if title == 'root' or title == '{init}': demo_path_output = f'[/{self.REPO_NAME}/]({demo_path} "view the result of {title}")' + elif title == '{workflows}': + demo_path_output = f'[/{self.REPO_NAME}/.github/workflows]({demo_path} "view the result of {title}")' + elif title == '{scripts}': + demo_path_output = f'[/{self.REPO_NAME}/.github/scripts]({demo_path} "view the result of {title}")' + elif title == '{others}': + demo_path_output = f'[/{self.REPO_NAME}/.github]({demo_path} "view the result of {title}")' # Appending all data together if condition is None: @@ -171,6 +217,14 @@ def update_table_of_contributors(self, condition): print('Successfully updated the contributor details !!!...') def update_table_of_content(self, condition): + """ + Update the table of content based on the specified condition. + + Args: + condition (callable): A function that takes one argument (i.e., the core contribution) + and returns True if the contribution should be included in the table, or + False otherwise. If None, then all core contributions are included. + """ # Calculating stating and ending points of the targeted table table_of_content_start, table_of_content_end = self.find_table_points('table-of-content') @@ -234,6 +288,15 @@ def update_table_of_content(self, condition): def main(): + """ + The main function of the script is responsible for updating the root index file and the index files of `Theory` and `Solved-Problems` directories. + + The function takes in environment variables `REPO_NAME` and uses it to fetch the required data from the contributors log file. + + The function then updates the root index file and the index files of `Theory` and `Solved-Problems` directories using the fetched data. + + The function also prints out a success message at the end. + """ # Retrieving Environmental variables REPO_NAME = os.environ.get('REPO_NAME') 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..cbfee37 --- /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/DSA/ "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/linting.yml b/.github/workflows/linting.yml index 1204313..a39226a 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -1,16 +1,17 @@ name: linter on: - pull_request: + pull_request: branches: [main] + paths-ignore: ['.github/**', '**.md'] permissions: - contents: read - packages: read - statuses: write + contents: read + packages: read + statuses: write jobs: - checkout: + checkout: name: checkout runs-on: ubuntu-latest outputs: @@ -20,101 +21,101 @@ jobs: needs_python_linting: ${{ steps.check_extension.outputs.python }} needs_other_linting: ${{ steps.check_extension.outputs.other }} steps: - - name: Checking out the repo - uses: actions/checkout@v4.1.1 - - name: Setup Python - uses: actions/setup-python@v4.7.1 - - name: Fetching PR Details - run: | + - name: Checking out the repo + uses: actions/checkout@v4.1.1 + - name: Setup Python + uses: actions/setup-python@v4.7.1 + - name: Fetching PR Details + run: | touch pr.json gh pr view $PR_NUMBER --json files > pr.json - env: - PR_NUMBER: ${{ github.event.pull_request.number }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Checking file extensions - id: check_extension - uses: jannekem/run-python-script-action@v1 - with: - script: | - import os - import json + env: + PR_NUMBER: ${{ github.event.pull_request.number }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Checking file extensions + id: check_extension + uses: jannekem/run-python-script-action@v1 + with: + script: | + import os + import json - # Setting default variables - checks = { lang:'false' for lang in ['c_cpp', 'java', 'javascript', 'python', 'other'] } - c_cpp_ext = ['.c', '.cpp', '.h', '.hpp', '.cc', '.hh', '.cxx', '.hxx'] + # Setting default variables + checks = { lang:'false' for lang in ['c_cpp', 'java', 'javascript', 'python', 'other'] } + c_cpp_ext = ['.c', '.cpp', '.h', '.hpp', '.cc', '.hh', '.cxx', '.hxx'] - # Reading contents of PR - with open('pr.json','r') as json_file: - data = json.load(json_file) + # Reading contents of PR + with open('pr.json','r') as json_file: + data = json.load(json_file) - # Iterating over data - for file in data["files"]: - path = file["path"] - - # Ending loop if all are 'true' - if all([val == 'true' for val in checks.values()]): - break + # Iterating over data + for file in data["files"]: + path = file["path"] + + # Ending loop if all are 'true' + if all([val == 'true' for val in checks.values()]): + break - # Checking for extensions - if os.path.exists(path): - for key,value in checks.items(): - if value == 'true': - continue - if any([path.endswith(ext) for ext in c_cpp_ext]): - checks['c_cpp']='true' - elif path.endswith('.java'): - checks['java']='true' - elif path.endswith('.js'): - checks['javascript']='true' - elif path.endswith('.py'): - checks['python']='true' - elif '.' in path.split('/')[-1] and not path.endswith('.md'): - checks['other']='true' + # Checking for extensions + if os.path.exists(path): + for key,value in checks.items(): + if value == 'true': + continue + if any([path.endswith(ext) for ext in c_cpp_ext]): + checks['c_cpp']='true' + elif path.endswith('.java'): + checks['java']='true' + elif path.endswith('.js'): + checks['javascript']='true' + elif path.endswith('.py'): + checks['python']='true' + elif '.' in path.split('/')[-1] and not (path.startswith('.github') or path.endswith('.md')): + checks['other']='true' - # Setting output variables based on file extensions - for lang,val in checks.items(): - os.system(f'echo "{lang}={val}" >> "$GITHUB_OUTPUT"') + # Setting output variables based on file extensions + for lang,val in checks.items(): + os.system(f'echo "{lang}={val}" >> "$GITHUB_OUTPUT"') - c-cpp-linter: + c-cpp-linter: needs: [checkout] if: ${{ needs.checkout.outputs.needs_c_cpp_linting == 'true' }} uses: Grow-with-Open-Source/C-CPP-Projects/.github/workflows/c-cpp-linter.yml@main - java-linter: + java-linter: needs: [checkout] if: ${{ needs.checkout.outputs.needs_java_linting == 'true' }} uses: Grow-with-Open-Source/Java-Projects/.github/workflows/java-linter.yml@main - javascript-linter: + javascript-linter: needs: [checkout] if: ${{ needs.checkout.outputs.needs_javascript_linting == 'true' }} uses: Grow-with-Open-Source/Javascript-Projects/.github/workflows/javascript-linter.yml@main - python-linter: + python-linter: needs: [checkout] if: ${{ needs.checkout.outputs.needs_python_linting == 'true' }} uses: Grow-with-Open-Source/Python-Projects/.github/workflows/python-linter.yml@main - - other-linter: - needs: [checkout, c-cpp-linter, java-linter, javascript-linter, python-linter] - if: ${{ - always() && - needs.checkout.outputs.needs_other_linting == 'true' || - ((needs.c-cpp-linter.result == 'skipped' || needs.checkout.outputs.needs_c_cpp_linting == 'false') && - (needs.java-linter.result == 'skipped' || needs.checkout.outputs.needs_java_linting == 'false') && - (needs.javascript-linter.result == 'skipped' || needs.checkout.outputs.needs_javascript_linting == 'false') && - (needs.python-linter.result == 'skipped' || needs.checkout.outputs.needs_python_linting == 'false')) - }} + + other-linter: + needs: + [checkout, c-cpp-linter, java-linter, javascript-linter, python-linter] + if: ${{ + always() && + needs.checkout.outputs.needs_other_linting == 'true' || + ((needs.c-cpp-linter.result == 'skipped' || needs.checkout.outputs.needs_c_cpp_linting == 'false') && + (needs.java-linter.result == 'skipped' || needs.checkout.outputs.needs_java_linting == 'false') && + (needs.javascript-linter.result == 'skipped' || needs.checkout.outputs.needs_javascript_linting == 'false') && + (needs.python-linter.result == 'skipped' || needs.checkout.outputs.needs_python_linting == 'false')) + }} runs-on: ubuntu-latest + steps: - - name: Checking out the repo - uses: actions/checkout@v4.1.1 - with: - fetch-depth: 0 - ref: ${{ github.event.pull_request.head.ref }} - - name: Super Linter - uses: super-linter/super-linter@v5.4.3 - env: - VALIDATE_ALL_CODEBASE: false - DEFAULT_BRANCH: main + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Super-linter + uses: super-linter/super-linter@v7.1.0 # x-release-please-version + env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 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