From 33d65963f8c3aea7fef499d267c05333cbbdfc55 Mon Sep 17 00:00:00 2001 From: Nicholas Felt Date: Thu, 15 Aug 2024 15:51:38 -0700 Subject: [PATCH] Initial repo setup (#1) * refactor: Add initial files * ci: Add basic GitHub template files * feat: Added the check-api-for-breaking-changes.yml reusable workflow * ci: Get pre-commit hooks to play nicely with each other * feat: Added an action to run CodeQL analysis * docs: Switch to tables for input documentation * docs: Break up the readme with line breaks * docs: Move each Action/Workflow document section into a separate markdown file * docs: Update codeql-analysis readme * feat: Added a workflow to validate Open Source community standards are being met in a repository * docs: Update docs to just use the main branch as the hash --- .gitattributes | 11 + .github/CODEOWNERS | 4 + .github/ISSUE_TEMPLATE/bug_report.yml | 43 ++++ .github/ISSUE_TEMPLATE/feature_request.yml | 24 +++ .github/PULL_REQUEST_TEMPLATE.md | 32 +++ .github/auto_assign.yml | 2 + .github/dependabot.yml | 26 +++ .github/workflows/codeql-analysis.yml | 27 +++ .../workflows/enforce-community-standards.yml | 10 + .gitignore | 1 + .pre-commit-config.yaml | 91 ++++++++ CHANGELOG.md | 19 ++ CODE_OF_CONDUCT.md | 74 +++++++ CONTRIBUTING.md | 121 +++++++++++ LICENSE.md | 194 ++++++++++++++++++ README.md | 51 +++++ SECURITY.md | 12 ++ actions/codeql-analysis/action.yml | 24 +++ actions/codeql-analysis/readme.md | 38 ++++ pyproject.toml | 80 ++++++++ workflows/check-api-for-breaking-changes.md | 29 +++ workflows/check-api-for-breaking-changes.yml | 40 ++++ workflows/enforce-community-standards.md | 36 ++++ workflows/enforce-community-standards.yml | 44 ++++ 24 files changed, 1033 insertions(+) create mode 100644 .gitattributes create mode 100644 .github/CODEOWNERS create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/auto_assign.yml create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/codeql-analysis.yml create mode 100644 .github/workflows/enforce-community-standards.yml create mode 100644 .pre-commit-config.yaml create mode 100644 CHANGELOG.md create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 SECURITY.md create mode 100644 actions/codeql-analysis/action.yml create mode 100644 actions/codeql-analysis/readme.md create mode 100644 pyproject.toml create mode 100644 workflows/check-api-for-breaking-changes.md create mode 100644 workflows/check-api-for-breaking-changes.yml create mode 100644 workflows/enforce-community-standards.md create mode 100644 workflows/enforce-community-standards.yml diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..9c1a3edd --- /dev/null +++ b/.gitattributes @@ -0,0 +1,11 @@ +# Set default behavior to automatically normalize line endings. +* text=auto + +# Force batch scripts to always use CRLF line endings so that if a repo is accessed +# in Windows via a file share from Linux, the scripts will work. +*.{cmd,[cC][mM][dD]} text eol=crlf +*.{bat,[bB][aA][tT]} text eol=crlf + +# Force bash scripts to always use LF line endings so that if a repo is accessed +# in Unix via a file share from Windows, the scripts will work. +*.sh text eol=lf diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000..21dc3651 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,4 @@ +# These owners will be the default owners for everything in +# the repo. Unless a later match takes precedence they +# will be requested for review when someone opens a pull request. +* @tektronix/python-package-ci-cd-admins diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000..834947d0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,43 @@ +--- +name: Bug Report +description: File a bug report here +title: '[BUG]: ' +labels: [bug] +body: + - type: markdown + attributes: + value: | + Thank you for taking the time to submit a bug report! + Please make sure there aren't any open/closed issues for this topic already. + - type: textarea + id: bug-description + attributes: + label: Description of the bug + description: Give us a brief description of what happened and what is the expected + behavior + validations: + required: true + - type: textarea + id: steps-to-reproduce + attributes: + label: Steps To Reproduce + description: Steps to reproduce the behavior. + placeholder: | + 1. Go to '...' + 2. Click on '...' + 3. Scroll down to '...' + 4. See error + validations: + required: true + - type: textarea + id: environment-information + attributes: + label: Environment Information + description: | + Please tell us about your environment: + - type: textarea + id: additional-information + attributes: + label: Additional Information + description: |- + Provide any additional information such as logs, screenshots, likes, scenarios in which the bug occurs so that it facilitates resolving the issue. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 00000000..4d764f9d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,24 @@ +--- +name: Feature Request +description: Request a new feature or enhancement +labels: [enhancement] +title: '[FEAT]: ' +body: + - type: markdown + attributes: + value: | + Please make sure this feature request hasn't been already submitted by someone by looking through other open/closed issues + - type: textarea + id: description + attributes: + label: Description + description: Give us a brief description of the feature or enhancement you would + like + validations: + required: true + - type: textarea + id: additional-information + attributes: + label: Additional Information + description: Give us some additional information on the feature request like + proposed solutions, links, screenshots, etc. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..b00ca7c7 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,32 @@ +## Proposed changes + +Please include a summary of the changes and any links to related issues. Please also include relevant motivation and context. + +Addresses #\< fill in issue number here > + +## Types of changes + +What types of changes does your code introduce? +_Put an `x` in the boxes that apply_ + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Functionality update (non-breaking change which updates or changes existing functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] CI/CD update (an update to the CI/CD workflows, scripts, and/or configurations) +- [ ] Documentation update (an update to enhance the user experience when reading through the docs) + +## Checklist + +_Put an `x` in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code._ + +- [ ] I have followed the guidelines in the [CONTRIBUTING](https://github.com/tektronix/tm_devices/blob/main/CONTRIBUTING.md) document +- [ ] I have signed the CLA +- [ ] I have checked to ensure there aren't other open [Pull Requests](https://github.com/tektronix/tm_devices/pulls) for the same update/change +- [ ] I have created (or updated) an [Issue](https://github.com/tektronix/tm_devices/issues) to track the status of this update/change and updated the link in this PR description (see above in the **Proposed changes** section) using the wording `Addresses #` +- [ ] I have performed a self-review of my code +- [ ] My code follows the style guidelines of this project +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] Basic linting passes locally with my changes +- [ ] I have added necessary documentation (if appropriate) +- [ ] I have updated the Changelog with a brief description of my changes diff --git a/.github/auto_assign.yml b/.github/auto_assign.yml new file mode 100644 index 00000000..a1fd978f --- /dev/null +++ b/.github/auto_assign.yml @@ -0,0 +1,2 @@ +--- +addAssignees: author diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..c9b851f9 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,26 @@ +--- +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + groups: + gh-actions-dependencies: + patterns: ['*'] + labels: [gh-actions, dependencies] + commit-message: + prefix: gh-actions + include: scope + - package-ecosystem: pip + directory: / + schedule: + interval: weekly + versioning-strategy: increase-if-necessary + groups: + python-dependencies: + patterns: ['*'] + labels: [python, dependencies] + commit-message: + prefix: python-deps + include: scope diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 00000000..d17b9b8c --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,27 @@ +--- +name: CodeQL +on: + push: + branches: [main] + pull_request: + branches: [main] + schedule: + - cron: 17 16 * * 4 +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + strategy: + fail-fast: false + matrix: + language: [python, javascript] + steps: + - name: Run CodeQL Analysis + uses: tektronix/python-package-ci-cd/actions/codeql-analysis@main + with: + language: ${{ matrix.language }} + codeql-queries: security-extended,security-and-quality diff --git a/.github/workflows/enforce-community-standards.yml b/.github/workflows/enforce-community-standards.yml new file mode 100644 index 00000000..e2b3d1f8 --- /dev/null +++ b/.github/workflows/enforce-community-standards.yml @@ -0,0 +1,10 @@ +--- +name: Enforce Open Source Community Standards +on: + push: + branches: [main] + pull_request: + branches: [main] +jobs: + enforce-community-standards: + uses: tektronix/python-package-ci-cd/workflows/enforce-community-standards.yml@main diff --git a/.gitignore b/.gitignore index f6083291..62da3829 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ python_semantic_release_templates/.previous_changelog_for_template.md python_semantic_release_templates/.previous_release_notes_for_template.md # Environments +poetry.lock .env*/ .venv*/ env*/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..85792999 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,91 @@ +--- +default_install_hook_types: [pre-commit, commit-msg] +default_stages: [pre-commit] +ci: + autofix_prs: false + autoupdate_schedule: quarterly +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: 2c9f875913ee60ca25ce70243dc24d5b6415598c # frozen: v4.6.0 + hooks: + - id: check-yaml + args: [--unsafe] + - id: check-toml + - id: check-json + - id: check-xml + - id: requirements-txt-fixer + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-case-conflict + - id: check-merge-conflict + - id: check-added-large-files + args: [--maxkb=3000, --enforce-all] + - id: forbid-submodules + - id: pretty-format-json + args: [--autofix, --indent=4] + - repo: https://github.com/Lucas-C/pre-commit-hooks + rev: a30f0d816e5062a67d87c8de753cfe499672b959 # frozen: v1.5.5 + hooks: + - id: remove-tabs + - id: forbid-tabs + - repo: https://github.com/python-jsonschema/check-jsonschema + rev: e2dde74d0702d15f4f43e4f4fb93e301b4bc1e30 # frozen: 0.29.1 + hooks: + - id: check-dependabot + - id: check-github-actions + files: action\.(yml|yaml) + - id: check-github-workflows + args: [--verbose] + files: ^(\.github/workflows/[^/]+|workflows/[^/]+)$ + - repo: https://github.com/commitizen-tools/commitizen + rev: d7e01aa9b0cfe3c1b732e66d523bbd0656221127 # frozen: v3.29.0 + hooks: + - id: commitizen + stages: [commit-msg] + - repo: https://github.com/adamchainz/blacken-docs + rev: 4c97c4a0d921007af6fefae92d8447cfbf63720b # frozen: 1.18.0 + hooks: + - id: blacken-docs + files: \.(rst|md|markdown|tex)$ + additional_dependencies: [black==24.4.2] # This may need to be updated/removed in the future once ruff supports formatting python code blocks in markdown + args: [--line-length=100] + - repo: https://github.com/lyz-code/yamlfix + rev: 47039c9bf8039e81f092c9777a1bc8be32fb7870 # frozen: 1.16.0 + hooks: + - id: yamlfix + - repo: https://github.com/executablebooks/mdformat + rev: 08fba30538869a440b5059de90af03e3502e35fb # frozen: 0.7.17 + hooks: + - id: mdformat + args: [--number, --end-of-line, keep] + additional_dependencies: + - setuptools # This is required since Python 3.12 no longer installs setuptools by default in virtual environments + - mdformat-admon + - mdformat-beautysh +# - mdformat-config + - mdformat-footnote + - mdformat-frontmatter + - mdformat-gfm + - mdformat-gfm-alerts + - mdformat-mkdocs + - mdformat-shfmt + - mdformat-simple-breaks + - mdformat-tables + - mdformat-toc + - mdformat-web + - mdformat-wikilink + - repo: https://github.com/pappasam/toml-sort + rev: b9b6210da457c38122995e434b314f4c4a4a923e # frozen: v0.23.1 + hooks: + - id: toml-sort-fix + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: 718fbf5fa5fb8cbe6aeac32a863271695104cd5d # frozen: v0.6.0 + hooks: + - id: ruff + args: [--fix, --exit-non-zero-on-fix] + - id: ruff-format + - repo: https://github.com/PyCQA/docformatter + rev: dfefe062799848234b4cd60b04aa633c0608025e # frozen: v1.7.5 + hooks: + - id: docformatter + additional_dependencies: [tomli] diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..1afa590e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,19 @@ +# Changelog + +The format is based on [Keep a Changelog](https://keepachangelog.com), and this +project adheres to [Semantic Versioning](https://semver.org). + +Valid subsections within a version are: + +- Added +- Changed +- Deprecated +- Removed +- Fixed +- Security + +--- + +## Unreleased + +Things to be included in the next release go here. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..3568f028 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,74 @@ +# Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and +expression, level of experience, education, socio-economic status, nationality, +personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery and unwelcome sexual attention or + advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic + address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, or to ban temporarily or permanently any +contributor for other behaviors that they deem inappropriate, threatening, +offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Reporting + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at: opensource@tektronix.com. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. You may not receive a +direct response to your email, but it is being reviewed. The project team is +obligated to maintain confidentiality with regard to the reporter of an +incident. Further details of specific enforcement policies may be posted +separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of leadership. + +## Attribution + +This Code of Conduct is adapted by Tektronix from the Contributor Covenant, +version 1.4, available at: +[contributor-covenant.org](https://www.contributor-covenant.org/version/1/4/code-of-conduct.html) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..755d54d5 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,121 @@ +# Contributing Guidelines + +Contributions are welcome, and they are greatly appreciated! Every bit helps, +and credit will always be given. + +## Commit Guidelines + +- Commit messages should follow the + [Angular style](https://python-semantic-release.readthedocs.io/en/latest/commit-parsing.html#semantic-release-commit-parser-angularcommitparser). + +## Types of Contributions + +There are several types of contributions that can be made: + +### Report Bugs + +If you are reporting a bug, please include: + +- Your operating system name and version. +- Any details about your local setup that might be helpful in troubleshooting. +- Detailed steps to reproduce the bug. + +### Fix Bugs + +Look through the GitHub issues for bugs. Anything tagged with "bug" and "help +wanted" is open to whoever wants to implement it. + +### Implement Features + +Look through the GitHub issues for features. Anything tagged with "enhancement" +and "help wanted" is open to whoever wants to implement it. + +### Submit Feedback + +If you are proposing a feature: + +- Explain in detail how it would work. +- Keep the scope as narrow as possible, to make it easier to implement. +- Remember that this is a volunteer-driven project, and that contributions are + welcome :) + +## Get Started! + +Ready to contribute? Here's how to set up `python-package-ci-cd` for local development. + +1. Set up commit signing, see [GitHub's documentation](https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification) for details. + + !!! hint + All commits going into the main repository are required to be signed, so make sure + to set up commit signing before starting to make changes. + +2. Fork `python-package-ci-cd` into a new repository. + +3. Set up a virtual environment and install the project with its dependencies: + + - Using the helper script (recommended): + ```console + python scripts/contributor_setup.py + ``` + +4. Check to see if there are any [open issues](https://github.com/tektronix/python-package-ci-cd/issues) or [pull requests](https://github.com/tektronix/python-package-ci-cd/pulls) that are related to the change you wish to make. + +5. Create or update an [issue](https://github.com/tektronix/python-package-ci-cd/issues) to track the status of your change. + +6. Use `git` to create a branch for local development and make your changes: + + ```console + git checkout -b name-of-your-bugfix-or-feature + ``` + +7. Update the **Unreleased** section in the [CHANGELOG](./CHANGELOG.md) using the proper format. + +8. When you're done making changes, check that your changes conform to any code + formatting requirements. + + !!! note + Always remember to activate the virtual environment. + + ```console + # Linux + source .venv/bin/activate + + # Windows + .venv\Scripts\activate.bat + ``` + + - To run the pre-commit checks: + + ```console + pre-commit run --all + ``` + +9. Commit and push your changes, then open a pull request from + the fork back into the main repository. + + - Commit messages must be structured as follows: + ``` + [optional scope]: + + [optional body] + + [optional footer(s)] + ``` + - `` can be one of `fix`, `feat`, `build`, `ci`, `docs`, `style`, + `refactor`, or `test`. + - See the + [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) + website for more details on this format. + +## Pull Request Guidelines + +Before you submit a pull request, check that it meets these guidelines: + +1. If the pull request adds functionality, the [README](./README.md) should be updated. +2. The **Unreleased** section in the [Changelog](./CHANGELOG.md) should be updated. + +## Code of Conduct + +Please note that the `python-package-ci-cd` project is released with a +[Code of Conduct](./CODE_OF_CONDUCT.md). By contributing to this project you agree +to abide by its terms. diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 00000000..0738cdc9 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,194 @@ +Apache License + +_Version 2.0, January 2004_ + +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +_END OF TERMS AND CONDITIONS_ + +``` +Copyright 2022 Tektronix + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +``` diff --git a/README.md b/README.md new file mode 100644 index 00000000..7c5e5642 --- /dev/null +++ b/README.md @@ -0,0 +1,51 @@ +| | | +| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Code Quality** | [![CodeQL status](https://github.com/tektronix/python-package-ci-cd/actions/workflows/codeql-analysis.yml/badge.svg?branch=main)](https://github.com/tektronix/python-package-ci-cd/actions/workflows/codeql-analysis.yml) [![CodeFactor grade](https://www.codefactor.io/repository/github/tektronix/python-package-ci-cd/badge)](https://www.codefactor.io/repository/github/tektronix/python-package-ci-cd) [![pre-commit status](https://results.pre-commit.ci/badge/github/tektronix/python-package-ci-cd/main.svg)](https://results.pre-commit.ci/latest/github/tektronix/python-package-ci-cd/main) | + +--- + +# GitHub Actions and Re-usable Workflows for Python Packaging CI/CD + +`python-package-ci-cd` is a collection of GitHub Actions and re-usable Workflows that enable +Python Packaging CI/CD. + +## Actions + +- [`codeql-analysis`](./actions/codeql-analysis/readme.md) + - This composite Action will checkout the code and then run a CodeQL analysis against the + provided languages in the repository. + +## Reusable Workflows + +- [`check-api-for-breaking-changes.yml`](./workflows/check-api-for-breaking-changes.md) + - This workflow will use the [`griffe`](https://mkdocstrings.github.io/griffe/) Python package to check for + any major or breaking changes in a package's API. +- [`enforce-community-standards.yml`](./workflows/enforce-community-standards.md) + - This workflow will ensure that all necessary files are in place in order to meet the + Open Source Community Standards for a repository. + +## Maintainers + +Before reaching out to any maintainers directly, please first check if +your issue or question is already covered by any [open +issues](https://github.com/tektronix/python-package-ci-cd/issues). If the issue or +question you have is not already covered, please [file a new +issue](https://github.com/tektronix/python-package-ci-cd/issues/new/choose) or +start a +[discussion](https://github.com/tektronix/python-package-ci-cd/discussions) and +the maintainers will review and respond there. + +- - For open-source policy and license questions. + +## Contributing + +Interested in contributing? Check out +the [contributing guidelines](https://github.com/tektronix/python-package-ci-cd/blob/main/CONTRIBUTING.md). Please +note that this project is released with +a [Code of Conduct](https://github.com/tektronix/python-package-ci-cd/blob/main/CODE_OF_CONDUCT.md). By +contributing to this project, you agree to abide by its terms. + +## License + +`python-package-ci-cd` was created by Tektronix. It is licensed under the terms of +the [Apache License 2.0](https://github.com/tektronix/python-package-ci-cd/blob/main/LICENSE.md). diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..4479e53c --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,12 @@ +# Security Policy + +## Supported Versions + +| Version | Supported | +| ------- | ------------------ | +| > 0.1.0 | :white_check_mark: | + +## Reporting a Vulnerability + +Please reach out directly to the maintainers to report a +potential vulnerability. **Do not file a public issue.** diff --git a/actions/codeql-analysis/action.yml b/actions/codeql-analysis/action.yml new file mode 100644 index 00000000..f8b7bbfe --- /dev/null +++ b/actions/codeql-analysis/action.yml @@ -0,0 +1,24 @@ +--- +name: Run CodeQL Analysis +description: Checkout the repository and then run CodeQL Analysis on the given language. +inputs: + language: + description: A valid language to analyze. + required: true + codeql-queries: + description: A comma-separate list of CodeQL query sets to use. + default: security-extended,security-and-quality +runs: + using: composite + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ inputs.language }} + queries: ${{ inputs.codeql-queries }} + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: /language:${{ inputs.language }} diff --git a/actions/codeql-analysis/readme.md b/actions/codeql-analysis/readme.md new file mode 100644 index 00000000..c26bd931 --- /dev/null +++ b/actions/codeql-analysis/readme.md @@ -0,0 +1,38 @@ +# codeql-analysis + +This composite Action will checkout the code and then run a CodeQL analysis against the +provided languages in the repository. See the +[CodeQL docs](https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning#changing-the-languages-that-are-analyzed) +for the complete list of supported languages. The `security-events` permission must be set to +`write` in order to allow CodeQL to create security events that show up in the repository's Security tab. + +## Inputs + +| Input variable | Necessity | Description | Default | +| ---------------- | --------- | -------------------------------------------------- | -------------------------------------- | +| `language` | required | The language to analyze. | | +| `codeql-queries` | optional | A comma-separate list of CodeQL query sets to use. | security-extended,security-and-quality | + +## Example + +```yaml +# .github/workflows/codeql-analysis.yml +name: CodeQL +on: + push: + branches: [main] +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write # Allow CodeQL to create security events + steps: + - name: Run CodeQL Analysis + uses: tektronix/python-package-ci-cd/actions/codeql-analysis@main # it is recommended to use the latest release tag instead of `main` + with: + language: python # required + codeql-queries: security-extended,security-and-quality # optional +``` diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..2c4ad87a --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,80 @@ +[tool] + +[tool.docformatter] +close-quotes-on-newline = true +in-place = true +recursive = true +wrap-descriptions = 100 +wrap-summaries = 0 + +[tool.poetry] +package-mode = false +version = "0.0.0" + +[tool.poetry.dependencies] +pip = "^24.0" +poetry = "^1.8.0" +poetry-audit-plugin = "^0.4.0" +poetry-core = "^1.9.0" +poetry-plugin-export = "^1.7.1" +poetry-pre-commit-plugin = "^0.1.2" +pre-commit = "^3.7" +python = "^3.11" +requests = "^2.32.3" +toml-sort = "^0.23.1" +tomli = "^2.0.1" +tomli-w = "^1.0.0" +yamlfix = "^1.16.0" + +[tool.ruff] +line-length = 100 +output-format = "concise" +src = ["."] + +[tool.ruff.lint] +allowed-confusables = ["¸", "×"] +fixable = ["ALL"] +flake8-pytest-style = {mark-parentheses = false} +flake8-quotes = {docstring-quotes = "double"} +ignore = [ +] +pydocstyle = {convention = "google"} +pylint = {max-args = 7} +# https://beta.ruff.rs/docs/rules/ +select = [ + "ALL" +] +task-tags = ["FIXME", "FUTURE", "RELIC", "TODO"] + +[tool.ruff.lint.isort] +force-sort-within-sections = false +known-first-party = [] +lines-between-types = 1 +order-by-type = false + +[tool.ruff.lint.per-file-ignores] + +[tool.semantic_release] +version_toml = [ + "pyproject.toml:tool.poetry.version" +] + +[tool.semantic_release.changelog] +exclude_commit_patterns = [] +template_dir = "python_semantic_release_templates" + +[tool.semantic_release.changelog.environment] +extensions = [] + +[tool.semantic_release.commit_parser_options] +# These settings allow python-semantic-release to be used without triggering on any commits +allowed_tags = [] +minor_tags = [] +patch_tags = [] + +[tool.tomlsort] +all = true +in_place = true +spaces_before_inline_comment = 2 +overrides."tool.poetry.*".inline_arrays = false +overrides."tool.pylint.*".table_keys = false diff --git a/workflows/check-api-for-breaking-changes.md b/workflows/check-api-for-breaking-changes.md new file mode 100644 index 00000000..fd6394d8 --- /dev/null +++ b/workflows/check-api-for-breaking-changes.md @@ -0,0 +1,29 @@ +# check-api-for-breaking-changes.yml + +This workflow will use the [`griffe`](https://mkdocstrings.github.io/griffe/) package to check for +any major or breaking changes in a package's API. It requires that the package be using the +`src` package layout. It runs on the `ubuntu-latest` runner label. +It uploads a file called `breaking_changes.md` as a workflow artifact that can be used with the +`publish-api-comparison.yml` workflow to post a comment on Pull Requests with details of changed APIs. + +## Inputs + +| Input variable | Necessity | Description | Default | +| -------------- | --------- | ------------------------------------------------------ | ------- | +| `package-name` | required | The name of the package to check for breaking changes. | | + +## Example + +```yaml +# .github/workflows/check-api-for-breaking-changes.yml +name: Check Public API for Breaking Changes +on: + pull_request: + branches: [main] +jobs: + check-api-for-breaking-changes: + uses: + tektronix/python-package-ci-cd/workflows/check-api-for-breaking-changes.yml@main # it is recommended to use the latest release tag instead of `main` + with: + package-name: my_package_name # required +``` diff --git a/workflows/check-api-for-breaking-changes.yml b/workflows/check-api-for-breaking-changes.yml new file mode 100644 index 00000000..66f4539e --- /dev/null +++ b/workflows/check-api-for-breaking-changes.yml @@ -0,0 +1,40 @@ +--- +name: Check Public API for Breaking Changes +on: + workflow_call: + inputs: + package-name: + description: The name of the package to check. + required: true + type: string +jobs: + check-api-for-breaking-changes: + name: Check API for breaking changes + runs-on: ubuntu-latest + env: + PACKAGE_NAME: ${{ inputs.package-name }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: x # any version + check-latest: true + - name: Install package to check + run: | + pip install --upgrade . + pip install griffe + - name: Check API for breaking changes + continue-on-error: true + run: | + echo "## Breaking API Changes" > breaking_changes.md + echo "\`\`\`" >> breaking_changes.md + griffe check --format=verbose --against=$(git rev-parse origin/main) --search=src "$PACKAGE_NAME" 2>&1 | tee -a breaking_changes.md + - name: Finish writing summary file + run: echo "\`\`\`" >> breaking_changes.md + - uses: actions/upload-artifact@v4 + with: + name: breaking_changes + path: breaking_changes.md diff --git a/workflows/enforce-community-standards.md b/workflows/enforce-community-standards.md new file mode 100644 index 00000000..b561be4b --- /dev/null +++ b/workflows/enforce-community-standards.md @@ -0,0 +1,36 @@ +# enforce-community-standards.yml + +This workflow will ensure that all necessary files are in place in order to meet the +Open Source Community Standards for a repository. The list of these files (and other settings) can +be found in the Community Standards section of the Insights tab of a public GitHub repository. You +can read about community profiles in +[GitHub's documentation](https://docs.github.com/en/communities/setting-up-your-project-for-healthy-contributions/about-community-profiles-for-public-repositories). + +The full list of files that this workflow checks for is as follows: + +- `.github/CODEOWNERS` +- `README.@(md|rst)` +- `CODE_OF_CONDUCT.@(md|rst)` +- `CONTRIBUTING.@(md|rst)` +- `LICENSE.@(md|rst)` +- `SECURITY.@(md|rst)` +- `.github/ISSUE_TEMPLATE/bug_report.@(yml|yaml)` +- `.github/ISSUE_TEMPLATE/feature_request.@(yml|yaml)` +- `.github/PULL_REQUEST_TEMPLATE.md` +- `.github/dependabot.@(yml|yaml)` +- `.github/workflows/codeql-analysis.@(yml|yaml)` + +## Example + +```yaml +# .github/workflows/enforce-community-standards.yml +name: Enforce Open Source Community Standards +on: + push: + branches: [main] + pull_request: + branches: [main] +jobs: + enforce-community-standards: + uses: tektronix/python-package-ci-cd/workflows/enforce-community-standards.yml@main # it is recommended to use the latest release tag instead of `main` +``` diff --git a/workflows/enforce-community-standards.yml b/workflows/enforce-community-standards.yml new file mode 100644 index 00000000..1af6730f --- /dev/null +++ b/workflows/enforce-community-standards.yml @@ -0,0 +1,44 @@ +--- +name: Enforce Open Source Community Standards +on: + push: + branches: [main] + pull_request: + branches: [main] +jobs: + enforce-community-standards: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + filename: + - .github/CODEOWNERS + - README.@(md|rst) + - CODE_OF_CONDUCT.@(md|rst) + - CONTRIBUTING.@(md|rst) + - LICENSE.@(md|rst) + - SECURITY.@(md|rst) + - .github/ISSUE_TEMPLATE/bug_report.@(yml|yaml) + - .github/ISSUE_TEMPLATE/feature_request.@(yml|yaml) + - .github/PULL_REQUEST_TEMPLATE.md + - .github/dependabot.@(yml|yaml) + - .github/workflows/codeql-analysis.@(yml|yaml) + steps: + - uses: actions/checkout@v4 + - name: Ensure ${{ matrix.filename }} exists + uses: andstor/file-existence-action@v3 + with: + files: ${{ matrix.filename }} + ignore_case: false + follow_symbolic_links: false + fail: true # Set the step to fail if the file doesn't exist + # Check that all jobs passed + check-enforce-community-standards-passed: + if: ${{ !cancelled() }} + needs: [enforce-community-standards] + runs-on: ubuntu-latest + steps: + - name: Decide whether the needed jobs succeeded or failed + uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }}