diff --git a/.github/.checkov.yaml b/.github/.checkov.yaml new file mode 100644 index 0000000..f743600 --- /dev/null +++ b/.github/.checkov.yaml @@ -0,0 +1,22 @@ +--- + +quiet: true + +skip-check: + # https://www.checkov.io/5.Policy%20Index/kubernetes.html + - CKV_K8S_15 # Image Pull Policy should be Always + - CKV_K8S_21 # The default namespace should not be used + - CKV_K8S_22 # Use read-only filesystem for containers where possible + - CKV_K8S_35 # Prefer using secrets as files over secrets as environment variables + - CKV_K8S_38 # Ensure that Service Account Tokens are only mounted where necessary + - CKV_K8S_40 # Containers should run as a high UID to avoid host conflict + - CKV_K8S_43 # Image should use digest + - CKV2_K8S_5 # No ServiceAccount/Node should be able to read all secrets + - CKV2_K8S_6 # Minimize the admission of pods which lack an associated NetworkPolicy + # https://www.checkov.io/5.Policy%20Index/dockerfile.html + - CKV_DOCKER_2 # Ensure that HEALTHCHECK instructions have been added to container images + # https://www.checkov.io/5.Policy%20Index/secrets.html + - CKV_SECRET_6 # Base64 High Entropy String + # https://www.checkov.io/5.Policy%20Index/github_actions.html + - CKV2_GHA_1 # Ensure top-level permissions are not set to write-all + - CKV_GHA_7 # The build output cannot be affected by user parameters other than the build entry point and the top-level source location. GitHub Actions workflow_dispatch inputs MUST be empty. diff --git a/.github/.editorconfig b/.github/.editorconfig new file mode 100644 index 0000000..0ded29a --- /dev/null +++ b/.github/.editorconfig @@ -0,0 +1,36 @@ +# To learn more about .editorconfig see https://aka.ms/editorconfigdocs +root = true + +[{*,.*}] +charset = utf-8 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.sh] +end_of_line = lf + +[{*.bat,*.cmd}] +end_of_line = crlf + +[*.go] +# gofmt defaults to LF for all the platforms: https://github.com/golang/go/issues/16355 +end_of_line = lf + +[*.md] +# Trailing whitespace is important in Markdown (they distinguish a new line from a new paragraph) +eclint_indent_style = unset +trim_trailing_whitespace = false + +[{go.mod,go.sum,*.go,.gitmodules}] +indent_size = 4 +indent_style = tab + +[Dockerfile] +indent_size = 4 + +[*.py] +profile = black + +[*.sh] +indent_size = 4 diff --git a/.github/.eslintrc.yml b/.github/.eslintrc.yml new file mode 100644 index 0000000..2d142f6 --- /dev/null +++ b/.github/.eslintrc.yml @@ -0,0 +1,17 @@ +--- +env: + es6: true + +extends: + - "eslint:recommended" + +parser: "@typescript-eslint/parser" + +plugins: + - "@typescript-eslint" + +rules: + no-undef: 'warn' + +globals: + module: "writable" diff --git a/.github/.flake8 b/.github/.flake8 new file mode 100644 index 0000000..6deafc2 --- /dev/null +++ b/.github/.flake8 @@ -0,0 +1,2 @@ +[flake8] +max-line-length = 120 diff --git a/.github/.gitattributes b/.github/.gitattributes new file mode 100644 index 0000000..569df3f --- /dev/null +++ b/.github/.gitattributes @@ -0,0 +1,126 @@ +############################### +# Qubership common # +############################### +.editorconfig text +.flake8 text +.gitattributes text +.gitignore text +.helmignore text +.prettierignore text + +*.env text eol=lf +*.json text +*.md text +*.mod text +*.robot text +*.sum text +*.tpl text +*.txt text +*.yaml text +*.yml text + +LICENSE text +Dockerfile text + +/CHANGELOG.md merge=union +/contributors.json merge=union +/CODE-OF-CONDUCT.md text +/CONTRIBUTING.md text +/README.md text +/SECURITY.md text + +############################### +# Git Line Endings # +############################### + +# Set default behaviour 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 +# gofmt defaults to LF for all the platforms: https://github.com/golang/go/issues/16355 +*.go text eol=lf + +########################################## +# Basic .gitattributes for a Java repo.# +########################################## + +# Java sources +*.java text diff=java +*.kt text diff=kotlin +*.groovy text diff=java +*.scala text diff=java +*.gradle text diff=java +*.gradle.kts text diff=kotlin + +# These files are text and should be normalized (Convert crlf => lf) +*.css text diff=css +*.scss text diff=css +*.sass text +*.df text +*.htm text diff=html +*.html text diff=html +*.js text +*.mjs text +*.cjs text +*.jsp text +*.jspf text +*.jspx text +*.properties text +*.tld text +*.tag text +*.tagx text +*.xml text + +# These files are binary and should be left untouched +# (binary is a macro for -text -diff) +*.class binary +*.dll binary +*.ear binary +*.jar binary +*.so binary +*.war binary +*.jks binary + +# Common build-tool wrapper scripts ('.cmd' versions are handled by 'Common.gitattributes') +mvnw text eol=lf +gradlew text eol=lf + +########################################## +# Basic .gitattributes for a python repo.# +########################################## + +# Source files +# ============ +*.pxd text diff=python +*.py text diff=python +*.py3 text diff=python +*.pyw text diff=python +*.pyx text diff=python +*.pyz text diff=python +*.pyi text diff=python + +# Binary files +# ============ +*.db binary +*.p binary +*.pkl binary +*.pickle binary +*.pyc binary export-ignore +*.pyo binary export-ignore +*.pyd binary + +# Jupyter notebook +*.ipynb text eol=lf + +# Note: .db, .p, and .pkl files are associated +# with the python modules ``pickle``, ``dbm.*``, +# ``shelve``, ``marshal``, ``anydbm``, & ``bsddb`` +# (among others). diff --git a/.github/.gitignore b/.github/.gitignore new file mode 100644 index 0000000..8b43eb3 --- /dev/null +++ b/.github/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +node_modules/ +node_modules/ diff --git a/.github/.golangci.yml b/.github/.golangci.yml new file mode 100644 index 0000000..b7f3374 --- /dev/null +++ b/.github/.golangci.yml @@ -0,0 +1,3 @@ +version: "2" +run: + timeout: 10m diff --git a/.github/.jscpd.json b/.github/.jscpd.json new file mode 100644 index 0000000..2ccd8d4 --- /dev/null +++ b/.github/.jscpd.json @@ -0,0 +1,9 @@ +{ + "threshold": 2, + "ignore": [ + "**/.git/**", + "**/charts/*/templates/*/*.yaml", + "**/charts/*/templates/*/*/*.yaml", + "**/docs/examples/**" + ] +} diff --git a/.github/.licenserc.yaml b/.github/.licenserc.yaml new file mode 100644 index 0000000..68854fe --- /dev/null +++ b/.github/.licenserc.yaml @@ -0,0 +1,15 @@ +header: + license: + spdx-id: Apache-2.0 + copyright-owner: Netcracker Technology Corporation + copyright-year: '2024-2025' + + paths-ignore: + - 'dist' + - 'licenses' + - '**/*.md' + - 'LICENSE' + - 'NOTICE' + - '.github' + + comment: on-failure diff --git a/.github/.markdownlint.json b/.github/.markdownlint.json new file mode 100644 index 0000000..35b8a36 --- /dev/null +++ b/.github/.markdownlint.json @@ -0,0 +1,11 @@ +{ + "default": true, + "MD004": { "style": "consistent" }, + "MD007": { "indent": 2 }, + "MD013": { "line_length": 120, "code_blocks": false, "tables": false }, + "MD024": { "siblings_only": true }, + "MD029": { "style": "one" }, + "MD033": { "allowed_elements": ["img", "br", "a", "p"] }, + "MD041": false, + "MD046": { "style": "fenced" } +} diff --git a/.github/.wwhrd.yml b/.github/.wwhrd.yml new file mode 100644 index 0000000..aa0c81a --- /dev/null +++ b/.github/.wwhrd.yml @@ -0,0 +1,7 @@ +allowlist: + - Apache-2.0 + - MIT + - BSD-3-Clause + - BSD-2-Clause + - ISC + - MPL-2.0 diff --git a/.github/.yaml-lint.yml b/.github/.yaml-lint.yml new file mode 100644 index 0000000..90238d5 --- /dev/null +++ b/.github/.yaml-lint.yml @@ -0,0 +1,66 @@ +--- +#### Config file for yamllint +# Rules: https://yamllint.readthedocs.io/en/stable/rules.html + +# Exclude not required files +# ignore-from-file: +# - .gitignore +# - .yamlignore + +rules: + braces: + min-spaces-inside: 1 + max-spaces-inside: 1 + min-spaces-inside-empty: 0 + max-spaces-inside-empty: 0 + brackets: + min-spaces-inside: 0 + max-spaces-inside: 1 + min-spaces-inside-empty: -1 + max-spaces-inside-empty: -1 + colons: + max-spaces-before: 0 + max-spaces-after: -1 + commas: + max-spaces-before: 0 + min-spaces-after: 1 + max-spaces-after: 1 + comments: + level: warning + require-starting-space: true + min-spaces-from-content: 1 + comments-indentation: + level: warning + document-end: disable + document-start: disable + # level: warning + # present: false + empty-lines: + level: warning + max: 2 + max-start: 0 + max-end: 2 + empty-values: + forbid-in-block-mappings: true + forbid-in-flow-mappings: true + hyphens: + max-spaces-after: 1 + indentation: + level: warning + spaces: 2 + indent-sequences: consistent + check-multi-line-strings: false + key-duplicates: enable + key-ordering: disable + line-length: disable + # max: 100 + # allow-non-breakable-words: true + # allow-non-breakable-inline-mappings: true + new-line-at-end-of-file: disable + new-lines: + type: unix + octal-values: + forbid-implicit-octal: false + forbid-explicit-octal: false + trailing-spaces: enable + truthy: disable diff --git a/.github/CODE-OF-CONDUCT.md b/.github/CODE-OF-CONDUCT.md new file mode 100644 index 0000000..f5b511b --- /dev/null +++ b/.github/CODE-OF-CONDUCT.md @@ -0,0 +1,73 @@ +# Code of Conduct + +This repository is governed by following code of conduct guidelines. + +We put collaboration, trust, respect and transparency as core values for our community. +Our community welcomes participants from all over the world with different experience, +opinion and ideas to share. + +We have adopted this code of conduct and require all contributors to agree with that to build a healthy, +safe and productive community for all. + +The guideline is aimed to support a community where all people should feel safe to participate, +introduce new ideas and inspire others, regardless of: + +* Age +* Gender +* Gender identity or expression +* Family status +* Marital status +* Ability +* Ethnicity +* Race +* Sex characteristics +* Sexual identity and orientation +* Education +* Native language +* Background +* Caste +* Religion +* Geographic location +* Socioeconomic status +* Personal appearance +* Any other dimension of diversity + +## Our Standards + +We are welcoming the following behavior: + +* Be respectful for different ideas, opinions and points of view +* Be constructive and professional +* Use inclusive language +* Be collaborative and show the empathy +* Focus on the best results for the community + +The following behavior is unacceptable: + +* Violence, threats of violence, or inciting others to commit self-harm +* Personal attacks, trolling, intentionally spreading misinformation, insulting/derogatory comments +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Derogatory language +* Encouraging unacceptable behavior +* Other conduct which could reasonably be considered inappropriate in a professional community + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of the Code of Conduct +and are expected to take appropriate actions 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. + +## Reporting + +If you believe you’re experiencing unacceptable behavior that will not be tolerated as outlined above, +please report to `opensourcegroup@netcracker.com`. All complaints will be reviewed and investigated and will result in a response +that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality +with regard to the reporter of an incident. + +Please also report if you observe a potentially dangerous situation, someone in distress, or violations of these guidelines, +even if the situation is not happening to you. diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..b29699b --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,12 @@ +##################################################### +# +# List of approvers for this repository +# +##################################################### + +# +# Learn about CODEOWNERS file format: +# https://help.github.com/en/articles/about-code-owners +# + +* @nookyo @borislavr diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000..292ce26 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,12 @@ +# Contribution Guide + +We'd love to accept patches and contributions to this project. +Please, follow these guidelines to make the contribution process easy and effective for everyone involved. + +## Contributor License Agreement + +You must sign the [Contributor License Agreement](https://pages.netcracker.com/cla-main.html) in order to contribute. + +## Code of Conduct + +Please make sure to read and follow the [Code of Conduct](CODE-OF-CONDUCT.md). diff --git a/.github/FETCH_HEAD b/.github/FETCH_HEAD new file mode 100644 index 0000000..fcd62c1 --- /dev/null +++ b/.github/FETCH_HEAD @@ -0,0 +1 @@ +01154b818dc4b2b96acd3e6804572db5d748564d '01154b818dc4b2b96acd3e6804572db5d748564d' of https://github.com/Netcracker/.github diff --git a/.github/HEAD b/.github/HEAD new file mode 100644 index 0000000..5f65783 --- /dev/null +++ b/.github/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 01154b818dc4b2b96acd3e6804572db5d748564d runner 1760529250 +0000 checkout: moving from master to main diff --git a/.github/LICENSE b/.github/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/.github/LICENSE @@ -0,0 +1,202 @@ + + 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 + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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/.github/Protect-main-branch.json b/.github/Protect-main-branch.json new file mode 100644 index 0000000..225990c --- /dev/null +++ b/.github/Protect-main-branch.json @@ -0,0 +1,52 @@ +{ + "id": 4997771, + "name": "Protect main branch", + "target": "branch", + "source_type": "Repository", + "source": "netcracker/qubership-workflow-hub", + "enforcement": "active", + "conditions": { + "ref_name": { + "exclude": [], + "include": [ + "~DEFAULT_BRANCH" + ] + } + }, + "rules": [ + { + "type": "deletion" + }, + { + "type": "non_fast_forward" + }, + { + "type": "pull_request", + "parameters": { + "required_approving_review_count": 1, + "dismiss_stale_reviews_on_push": true, + "require_code_owner_review": true, + "require_last_push_approval": false, + "required_review_thread_resolution": true, + "automatic_copilot_code_review_enabled": false, + "allowed_merge_methods": [ + "merge", + "squash", + "rebase" + ] + } + } + ], + "bypass_actors": [ + { + "actor_id": 2, + "actor_type": "RepositoryRole", + "bypass_mode": "always" + }, + { + "actor_id": 1278589, + "actor_type": "Integration", + "bypass_mode": "always" + } + ] +} diff --git a/.github/README.md b/.github/README.md new file mode 100644 index 0000000..85477de --- /dev/null +++ b/.github/README.md @@ -0,0 +1,79 @@ +# Qubership GitHub Workflow Templates + +In this repository in folder [workflow-templates](./workflow-templates/) you can find GitHub Actions workflow templates for common CI/CD, release, and automation tasks across Qubership and Netcracker repositories. These templates help standardize and accelerate automation for various languages and use cases. + +## Table of contents + +- [Qubership GitHub Workflow Templates](#qubership-github-workflow-templates) + - [Table of contents](#table-of-contents) + - [How to Use](#how-to-use) + - [Available Workflow Templates](#available-workflow-templates) + - [References](#references) + - [Qubership Workflow Hub Documentation](#qubership-workflow-hub-documentation) + - [GitHub Actions Documentation](#github-actions-documentation) + - [Maven project configuration for release](#maven-project-configuration-for-release) + - [Organization level secrets reference](#organization-level-secrets-reference) + - [Git local pre-commit hook](#git-local-pre-commit-hook) + - [Configuration files examples](#configuration-files-examples) + +## How to Use + +1. **Copy the desired workflow YAML file** from this folder into your repository's `.github/workflows/` directory. +2. **Review and update required secrets and configuration files** as described in the comments at the top of each workflow file. Example config files are available in `config/examples/`. +3. **Customize input parameters** (such as version, tags, or build options) as needed for your project. +4. **Commit and push** the workflow to your repository. + +## Available Workflow Templates + +| Workflow Name | Description | Typical Use Case / Trigger | Workflow File | +|------------------------------|---------------------------------------------------------------------------------------------|-------------------------------------------|---------------| +| [**Add License Headers**](./docs/workflows/license-header.md) | Checks or adds license header into source code files.
Requires a [`.licenserc.yaml`](./config/examples/.licenserc.yaml) config file in the root folder. | On `push` and `workflow_dispatch` events | [license-header.yml](./workflow-templates/license-header.yml) | +| [**Automatic PR Labeler**](./docs/workflows/automatic-pr-labeler.md) | Automatically label PRs based on conventional commit messages.
Requires a [auto-labeler-config.yaml](./config/examples/auto-labeler-config.yaml) config file in the `.github` folder | On PR events | [automatic-pr-labeler.yaml](./workflow-templates/automatic-pr-labeler.yaml) | +| [**CDXGen**](./docs/workflows/cdxgen.md) | Generate SBOM (Software Bill of Materials) and vulnerability scan report | On push to main, manual trigger | [cdxgen.yaml](./workflow-templates/cdxgen.yaml) | +| [**Check Go Modules Licenses**](./docs/workflows/check-license.md) | Check the licenses of Go modules in the repository using a configurable allowlist.
Fails if any module has a disallowed or missing license.
Requires a [.wwhrd.yml](./config/examples/.wwhrd.yml) config file in the repository root. | On push | [check-license.yaml](./workflow-templates/check-license.yaml) | +| [**CLA Assistant**](./docs/workflows/cla.md) | Check if PR authors have signed the Contributor License Agreement | On PR events | [cla.yaml](./workflow-templates/cla.yaml) | +| [**Cleanup Old Docker**](./docs/workflows/cleanup-old-docker-container.md) | Clean up old Docker container versions in GitHub Packages | Scheduled (cron), manual trigger | [cleanup-old-docker-container.yaml](./workflow-templates/cleanup-old-docker-container.yaml) | +| [**Dependency Review**](./docs/workflows/dependency-review.md) | Analyze new and updated dependencies for vulnerabilities, license issues, and OpenSSF Scorecard results on PRs and manual runs. | On pull request, manual trigger | [dependency-review.yaml](./workflow-templates/dependency-review.yaml) | +| [**Dev Docker Build**](./docs/workflows/dev-docker-build.md) | Build and publish Docker images for development, supports dry-run and custom tags.
Can be configured by [.github/docker-build-config.json](./config/examples/docker-build-config.json) file. [More info](https://github.com/Netcracker/qubership-workflow-hub/tree/main/actions/docker-action#example-configuration) | Manual trigger (workflow_dispatch) | [dev-docker-build.yml](./workflow-templates/dev-docker-build.yml) | +| [**Dev Maven Docker Build**](./docs/workflows/dev-mvn-docker-build.md) | Development build for Maven projects, with Docker image build and artifact publishing | Manual trigger (workflow_dispatch) | [dev-mvn-docker-build.yml](./workflow-templates/dev-mvn-docker-build.yml) | +| [**Docker Release**](./docs/workflows/docker-release.md) | Build and publish Docker images to GitHub Container Registry, create GitHub release | On push to main, manual trigger | [docker-release.yaml](./workflow-templates/docker-release.yaml) | +| [**Go Build**](./docs/workflows/go-build.md) | Build and test Go projects, upload coverage to SonarCloud | On push to main, on pull request | [go-build.yaml](./workflow-templates/go-build.yaml) | +| [**Helm Charts Release**](./docs/workflows/helm-charts-release.md) | Release Helm charts and Docker images, create GitHub release.
Requires a lot of configuration. Please read workflow file comments.
Configuration examples:
[.github/helm-charts-release-config.yaml](./config/examples/helm-charts-release-config.yaml)
[.github/docker-build-config.json](./config/examples/docker-build-config.json)
[.github/release-drafter-config.yml](./config/examples/release-drafter-config.yml) | Manual trigger (workflow_dispatch) | [helm-charts-release.yaml](./workflow-templates/helm-charts-release.yaml) | +| [**Link Checker**](./docs/workflows/link-checker.md) | Check Markdown files for broken links using lychee | On push, manual trigger | [link-checker.yaml](./workflow-templates/link-checker.yaml) | +| [**Lint Codebase**](./docs/workflows/super-linter.md) | Lint codebase using GitHub Super-Linter. Runs multiple linters on changed files for supported languages.
See [.github/super-linter.env](.github/super-linter.env) and [.github/linters/](.github/linters/) for configuration. | On push, pull request, manual trigger | [super-linter.yaml](./workflow-templates/super-linter.yaml) | +| [**Maven Release v2**](./docs/workflows/maven-release-v2.md) | Enhanced Maven release with dry-run, Docker build, and GitHub release support.
Requires `pom.xml` [configuration](./docs/maven-publish-pom-preparation_doc.md) and [.github/release-drafter-config.yml](./config/examples/release-drafter-config.yml) config file. | Manual trigger (workflow_dispatch) | [maven-release-v2.yaml](./workflow-templates/maven-release-v2.yaml) | +| [**Maven Release**](./docs/workflows/maven-release.md) | Release and upload Java artifacts to Maven Central or GitHub Packages, create GitHub release | Manual trigger (workflow_dispatch) | [maven-release.yaml](./workflow-templates/maven-release.yaml) | +| [**Maven Snapshot Deploy**](./docs/workflows/maven-snapshot-deploy.md) | Deploy Maven snapshot artifacts to GitHub Packages or Maven Central | On push to non-main/non-release branches | [maven-snapshot-deploy.yaml](./workflow-templates/maven-snapshot-deploy.yaml) | +| [**PR Assigner**](./docs/workflows/pr-assigner.md) | Automatically assign reviewers to PRs based on config or CODEOWNERS | On PR events | [pr-assigner.yml](./workflow-templates/pr-assigner.yml) | +| [**PR Conventional Commits**](./docs/workflows/pr-conventional-commits.md) | Check if PR commits follow conventional commit messages | On PR events | [pr-conventional-commits.yaml](./workflow-templates/pr-conventional-commits.yaml) | +| [**PR Lint Title**](./docs/workflows/pr-lint-title.md) | Lint PR titles to ensure they follow conventional commit strategy | On PR events | [pr-lint-title.yaml](./workflow-templates/pr-lint-title.yaml) | +| [**Profanity Filter**](./docs/workflows/profanity-filter.md) | Check PRs, issues, and comments for profanity | On PR/issue/comment events | [profanity-filter.yaml](./workflow-templates/profanity-filter.yaml) | +| [**NPM Publish**](./docs/workflows/npm-publish.md) | Publish npm packages to GitHub Packages or npm registry, supports Lerna monorepos | Manual trigger (workflow_dispatch) | [npm-publish.yaml](./workflow-templates/npm-publish.yaml) | +| [**Python Release**](./docs/workflows/python-release.md) | Publish Python packages to PyPI and create GitHub release | Manual trigger (workflow_dispatch) | [python-release.yaml](./workflow-templates/python-release.yaml) | +| [**Scorecard supply-chain security**](./docs/workflows/ossf-scorecard.md) | Generates and optionaly publishes OSSF scorecard of the repository | On push to `main` and weekly schedule | [ossf-scorecard.yaml](./workflow-templates/ossf-scorecard.yaml) | +| [**SBOM to Release**](./docs/workflows/sbom-to-release.md) | Generate SBOM and upload it as a GitHub Release asset | On release, manual trigger | [sbom-to-release.yaml](./workflow-templates/sbom-to-release.yaml) | + +## References + +### [Qubership Workflow Hub Documentation](https://github.com/netcracker/qubership-workflow-hub) + +### [GitHub Actions Documentation](https://docs.github.com/en/actions) + +### [Maven project configuration for release](./docs/maven-publish-pom-preparation_doc.md) + +### [Organization level secrets reference](https://github.com/Netcracker/qubership-workflow-hub?tab=readme-ov-file#the-organization-level-secrets-and-vars-used-in-actions) + +### [Git local pre-commit hook](./docs/git-pre-commit-hook.md) + +## Configuration files examples + +- [Automatic PR Labeler](./config/examples/auto-labeler-config.yaml) +- [Docker build](./config/examples/docker-build-config.json) +- [Docker metadata](./config/examples/metadata-config.yml) +- [Helm charts release](./config/examples/helm-charts-release-config.yaml) +- [Release notes auto-generation](./config/examples/release-drafter-config.yml) +- [Release assets upload](./config/examples/assets-config.yml) + + +--- +For questions or improvements, please open an issue or PR in this repository. diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 0000000..63af6e7 --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,17 @@ +# Security Policy + +## Reporting a Vulnerability + +Please, report any security issue to `opensourcegroup@netcracker.com` where the issue will be triaged appropriately. + +If you know of a publicly disclosed security vulnerability please IMMEDIATELY email `opensourcegroup@netcracker.com` +to inform the team about the vulnerability, so we may start the patch, release, and communication process. + +## Security Release Process + +If the vulnerability is found in the latest stable release, then it would be fixed in patch version for that release. +E.g., issue is found in 2.5.0 release, then 2.5.1 version with a fix will be released. +By default, older versions will not have security releases. + +If the issue doesn't affect any existing public releases, the fix for medium and high issues is performed +in a main branch before releasing a new version. For low priority issues the fix can be planned for future releases. diff --git a/.github/actionlint.yml b/.github/actionlint.yml new file mode 100644 index 0000000..bd56f26 --- /dev/null +++ b/.github/actionlint.yml @@ -0,0 +1,9 @@ +paths: + .github/workflows/**/*.{yml,yaml}: + ignore: + - 'shellcheck reported issue in this script: SC2086:info.+' + - 'shellcheck reported issue in this script: SC2002:style.+' + actions/**/*.{yml,yaml}: + ignore: + - 'shellcheck reported issue in this script: SC2086:info.+' + - 'shellcheck reported issue in this script: SC2002:style.+' diff --git a/.github/applypatch-msg.sample b/.github/applypatch-msg.sample new file mode 100755 index 0000000..a5d7b84 --- /dev/null +++ b/.github/applypatch-msg.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +commitmsg="$(git rev-parse --git-path hooks/commit-msg)" +test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} +: diff --git a/.github/assets-config.yml b/.github/assets-config.yml new file mode 100644 index 0000000..3835e06 --- /dev/null +++ b/.github/assets-config.yml @@ -0,0 +1,7 @@ +archives: + - source: charts + outputName: helm-charts + archiveType: tar.gz + - source: docs + outputName: docs + archiveType: tar diff --git a/.github/auto-assign-project-to-issue.md b/.github/auto-assign-project-to-issue.md new file mode 100644 index 0000000..98899f8 --- /dev/null +++ b/.github/auto-assign-project-to-issue.md @@ -0,0 +1,50 @@ +# Auto-Assign Project to Issue + +## Overview + +The Auto-Assign Project to Issue workflow automatically assigns a project to an issue based on the issue's labels. This workflow template can be used to streamline project management by ensuring that issues are categorized and tracked in the appropriate projects. + +## Trigger + +This workflow is triggered when: +- An issue is opened +- An issue is edited +- An issue is reopened + +## Workflow Details + +### Jobs + +#### `add-to-project` +- **Runner**: `ubuntu-latest` +- **Purpose**: Adds the issue to a specified GitHub project + +### Steps + +1. **Add issue to project** + - Uses `actions/add-to-project@v1.0.2` + - Adds the issue to the project specified by `vars.PROJECT` + - Requires `ADD_PROJECT_TO_ISSUE_PAT` secret for authentication + +2. **Log info** + - Logs the issue number and title + - Logs the project number that the issue was added to + +## Configuration + +### Required Variables +- `PROJECT`: The project number to assign issues to + +### Required Secrets +- `ADD_PROJECT_TO_ISSUE_PAT`: Personal Access Token with permissions to add issues to projects + +## Usage + +This workflow is designed to work with GitHub's beta project feature. When an issue is created or modified, it will automatically be added to the specified project for better organization and tracking. + +## Categories +- Automation + +## Labels +- issues +- projects diff --git a/.github/auto-assign-project-to-issue.properties.json b/.github/auto-assign-project-to-issue.properties.json new file mode 100644 index 0000000..d0800d1 --- /dev/null +++ b/.github/auto-assign-project-to-issue.properties.json @@ -0,0 +1,12 @@ +{ + "name": "Auto-Assign Project to Issue", + "description": "automatically assigns a project to an issue based on the issue's labels. This workflow template can be used to streamline project management by ensuring that issues are categorized and tracked in the appropriate projects.", + "categories": [ + "Automation" + ], + "labels": [ + "issues", + "projects", + "preview" + ] +} \ No newline at end of file diff --git a/.github/auto-assign-project-to-issue.yml b/.github/auto-assign-project-to-issue.yml new file mode 100644 index 0000000..876ead5 --- /dev/null +++ b/.github/auto-assign-project-to-issue.yml @@ -0,0 +1,21 @@ +name: Auto-Assign Project to Issue +run-name: Issue ${{ github.event.issue.number }} -> Project ${{ vars.PROJECT }} +on: + issues: + types: [opened, edited, reopened] + +jobs: + add-to-project: + runs-on: ubuntu-latest + steps: + - name: Add issue to project + id: add_project + uses: actions/add-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2 + with: + project-url: https://github.com/orgs/Netcracker/projects/${{ vars.PROJECT }}?type=beta + github-token: ${{ secrets.ADD_PROJECT_TO_ISSUE_PAT }} + + - name: Log info + run: | + echo "▶ Triggered by issue #${{ github.event.issue.number }}: ${{ github.event.issue.title }}" + echo "▶ Added to Project #${{ vars.PROJECT }} (beta)" \ No newline at end of file diff --git a/.github/auto-labeler-config.yaml b/.github/auto-labeler-config.yaml new file mode 100644 index 0000000..2f4904b --- /dev/null +++ b/.github/auto-labeler-config.yaml @@ -0,0 +1,23 @@ +--- +conventional-commits: + - type: 'fix' + nouns: ['FIX', 'Fix', 'fix', 'FIXED', 'Fixed', 'fixed'] + labels: ['bug'] + - type: 'feature' + nouns: ['FEATURE', 'Feature', 'feature', 'FEAT', 'Feat', 'feat'] + labels: ['enhancement'] + - type: 'breaking_change' + nouns: ['BREAKING CHANGE', 'BREAKING', 'MAJOR'] + labels: ['breaking-change'] + - type: 'refactor' + nouns: ['refactor', 'Refactor'] + labels: ['refactor'] + - type: 'documentation' + nouns: ['docs', 'doc', 'document', 'documentation'] + labels: ['documentation'] + - type: 'build' + nouns: ['build', 'rebuild'] + labels: ['build'] + - type: 'config' + nouns: ['config', 'conf', 'configuration', 'configure'] + labels: ['config'] diff --git a/.github/automatic-pr-labeler.md b/.github/automatic-pr-labeler.md new file mode 100644 index 0000000..9816f64 --- /dev/null +++ b/.github/automatic-pr-labeler.md @@ -0,0 +1,27 @@ +# Automatic PR labels based on conventional commits + +The workflow automatically label PR on it's open/reopen events. It checks all the commit messages for certain words and apply corresponding labels to PR. Those labels used by several workflows to generate release notes. + +## Step 1: Create workflow file + +Create a new workflow in your repository. Copy the [prepared file](https://github.com/Netcracker/.github/blob/main/workflow-templates/automatic-pr-labeler.yaml) into `.github/workflows` directory of your repository. + +## Step 2: Add configuration file + +Create a new configuration file `.github/auto-labeler-config.yaml`. Copy [prepared file](https://github.com/Netcracker/.github/blob/main/config/examples/auto-labeler-config.yaml) into `.github` directory of your repository. + +## Step 3: Follow the conventional commits messages strategy + +The configuration file from [previous step](#step-2-add-configuration-file) defines the next rules for PR labeling based on words in **commit messages**: + +| Commit message word(s) | Label | +| ------------------------------------------------------- | --------------- | +| 'FIX', 'Fix', 'fix', 'FIXED', 'Fixed', 'fixed' | bug | +| 'FEATURE', 'Feature', 'feature', 'FEAT', 'Feat', 'feat' | enhancement | +| 'BREAKING CHANGE', 'BREAKING', 'MAJOR' | breaking-change | +| 'refactor','Refactor' | refactor | +| 'doc','docs','document','documentation' | documentation | +| 'build','rebuild' | build | +| 'config', 'conf', 'configuration', 'configure' | config | + +Labels on PRs used to generate release notes for GitHub releases. You can edit labels configuration and [release notes generation template](../../config/examples/release-drafter-config.yml) to extend or improve the default ones. diff --git a/.github/automatic-pr-labeler.properties.json b/.github/automatic-pr-labeler.properties.json new file mode 100644 index 0000000..040ab1f --- /dev/null +++ b/.github/automatic-pr-labeler.properties.json @@ -0,0 +1,8 @@ +{ + "name": "Qubership Automatic PR Labeler", + "description": "Automatic PR Labeler workflow template. It can be used to automatically label PRs based on the conventional commits messages.", + "categories": [ + "Automation", + "utilities" + ] +} diff --git a/.github/automatic-pr-labeler.yaml b/.github/automatic-pr-labeler.yaml new file mode 100644 index 0000000..57ded16 --- /dev/null +++ b/.github/automatic-pr-labeler.yaml @@ -0,0 +1,56 @@ +--- + +# The workflow template for automatic PR labeler. +# It requires to have a configuration file with labels and conditions to apply them. +# The configuration file should be placed in the .github folder and named auto-labeler-config.yaml. +# Example file can be found there: +# https://github.com/Netcracker/.github/blob/main/config/examples/auto-labeler-config.yaml + +name: Automatic PR Labeler + +on: + pull_request: + branches: [main] + types: + [opened, reopened, synchronize] + +permissions: + contents: read + +jobs: + assign-labels: + if: (github.event.pull_request.merged == false) && (github.event.pull_request.user.login != 'dependabot[bot]') && (github.event.pull_request.user.login != 'github-actions[bot]') + permissions: + pull-requests: write + contents: read + issues: write + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + + - name: "Execute assign labels" + id: action-assign-labels + uses: mauroalderete/action-assign-labels@671a4ca2da0f900464c58b8b5540a1e07133e915 # v1.5.1 + with: + pull-request-number: ${{ github.event.pull_request.number }} + github-token: ${{ github.token }} + conventional-commits: "./.github/auto-labeler-config.yaml" + maintain-labels-not-matched: true + apply-changes: ${{ github.event.pull_request.base.repo.id == github.event.pull_request.head.repo.id }} + + - name: Set labels-next safely + if: ${{ github.event.pull_request.base.repo.id != github.event.pull_request.head.repo.id }} + run: | + echo "LABELS_NEXT=$(echo ${STEPS_ACTION_ASSIGN_LABELS_OUTPUTS_LABELS_NEXT} | tr -dc 'a-zA-Z0-9-,')" >> $GITHUB_ENV + env: + STEPS_ACTION_ASSIGN_LABELS_OUTPUTS_LABELS_NEXT: ${{ steps.action-assign-labels.outputs.labels-next }} + - name: "Drop warning if PR from fork" + if: ${{ github.event.pull_request.base.repo.id != github.event.pull_request.head.repo.id }} + run: | + { + echo "⚠️ Pull request from fork! ⚠️"; + echo "Labels will not be applied to PR. Assign them manually please."; + echo "Labels to assign: '${LABELS_NEXT}'"; + } >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/broadcast-files-config.yaml b/.github/broadcast-files-config.yaml new file mode 100644 index 0000000..e2ccdaf --- /dev/null +++ b/.github/broadcast-files-config.yaml @@ -0,0 +1,124 @@ +common_files: + bot_branch_name: broadcast-common-files + patterns_to_include: > + .gitattributes, .editorconfig + destination: . + commit_message: 'chore: update of common files' +common_config_files: + bot_branch_name: broadcast-config-files + patterns_to_include: > + config/examples/auto-labeler-config.yaml, + config/examples/release-drafter-config.yml + destination: .github/ + repos_to_ignore: > + KubeMarine, k8s-conformance, gatekeeper-library, + cassandra-exporter, pg_hint_plan + commit_message: 'chore: update of common config files' +common_workflows: + patterns_to_include: > + workflow-templates/cla.yaml, + workflow-templates/super-linter.yaml, + workflow-templates/automatic-pr-labeler.yaml, + workflow-templates/pr-conventional-commits.yaml, + workflow-templates/pr-lint-title.yaml, + workflow-templates/link-checker.yaml + workflow-templates/ossf-scorecard.yaml + destination: .github/workflows + repos_to_ignore: > + KubeMarine, k8s-conformance, gatekeeper-library, + cassandra-exporter, pg_hint_plan + bot_branch_name: broadcast-workflows + topics_to_include: qubership-tp + commit_message: 'chore: update of common workflows' +ossf_workflow: + patterns_to_include: > + workflow-templates/ossf-scorecard.yaml + topics_to_include: qubership-ossf-request + destination: .github/workflows + bot_branch_name: broadcast-ossf-workflow + commit_message: 'chore: update of common workflows' +cloud_core_dependabot: + patterns_to_include: 'config/dependabot/cloud-core/dependabot.yml' + destination: .github/ + topics_to_include: core + committer_username: NetcrackerCLPLCI + bot_branch_name: broadcast-dependabot-configs + commit_message: 'chore: update cloud-core dependabot config file' +obsoleted_workflow_cleanup: + patterns_to_remove: > + pr-collect-commit-messages.yaml + prettier.yaml + profanity-filter.yaml + repos_to_ignore: > + KubeMarine, k8s-conformance, gatekeeper-library, + cassandra-exporter, pg_hint_plan + bot_branch_name: broadcast-workflows-cleanup + commit_message: 'chore: cleanup of obsoleted workflows' +maven_release_workflow: + patterns_to_include: workflow-templates/maven-release.yaml + destination: .github/workflows + bot_branch_name: broadcast-maven-release + commit_message: | + fix(ci): update of maven-release workflow + Related issue: https://github.com/Netcracker/.github/issues/89 +link_checker: + patterns_to_include: workflow-templates/link-checker.yaml + destination: .github/workflows + repos_to_ignore: > + KubeMarine, k8s-conformance, gatekeeper-library, + cassandra-exporter, pg_hint_plan + bot_branch_name: broadcast-link-checker-fix + commit_message: | + fix(ci): fix for link-checker workflow + Related issue: https://github.com/Netcracker/.github/issues/104 +cla_workflow: + patterns_to_include: > + workflow-templates/cla.yaml + destination: .github/workflows + bot_branch_name: broadcast-cla-workflow + commit_message: | + chore(ci): update of CLA workflow + Pinned `contributor-assistant/github-action` version to v2.6.1 SHA +maven_release_workflow_v2: + patterns_to_include: workflow-templates/maven-release-v2.yaml + destination: .github/workflows + bot_branch_name: broadcast-maven-release-v2 + commit_message: | + feat(ci): Broadcast maven-release-v2 workflow to QIP repos + Related issue: https://github.com/Netcracker/.github/issues/136 +pr_auto_assigner: + patterns_to_include: workflow-templates/pr-assigner.yml + destination: .github/workflows + bot_branch_name: broadcast-pr-auto-assigner + repos_to_ignore: > + qubership-profiler-agent + commit_message: | + fix(ci): update PR auto-assignment workflow to use pull_request event and improve fork handling + Related issue: pull_request_target vulnerability (https://nx.dev/blog/s1ngularity-postmortem) +secutiry_scan: + patterns_to_include: workflow-templates/security-scan.yml + destination: .github/workflows + bot_branch_name: broadcast-security-scan + commit_message: | + feat(ci): add security-scan workflow to scan for vulnerabilities in dependencies + Related issue: https://github.com/Netcracker/qubership-workflow-hub/issues/434 +conventional-commits: + patterns_to_include: workflow-templates/pr-conventional-commits.yaml + destination: .github/workflows + bot_branch_name: broadcast-conventional-commits + commit_message: | + feat(ci): enforce conventional commits in PR titles + Related issue: https://github.com/Netcracker/qubership-workflow-hub/issues/432 +common_config_files_autolabler: + bot_branch_name: broadcast-autolabler-config-files + patterns_to_include: > + config/examples/auto-labeler-config.yaml, + destination: .github/ + repos_to_ignore: > + KubeMarine, k8s-conformance, gatekeeper-library, + cassandra-exporter, pg_hint_plan + commit_message: > + chore: update of common autolabler config files + Related issue: https://github.com/Netcracker/qubership-workflow-hub/issues/433 + + diff --git a/.github/broadcast-files.yaml b/.github/broadcast-files.yaml new file mode 100644 index 0000000..ffde5b0 --- /dev/null +++ b/.github/broadcast-files.yaml @@ -0,0 +1,125 @@ +--- +name: Broadcast files to organization +run-name: "${{ inputs.config-file }}. ${{ inputs.section }} files broadcast to ${{ inputs.repos || 'all repositories' }}" +on: + workflow_dispatch: + inputs: + repos: + description: | + Target repositorys names. Comma-separated + If not provided, the action will be triggered for all repositories in the organization. + required: false + type: string + config-file: + description: "Config file relative path" + required: true + type: string + default: ".github/broadcast-files-config.yaml" + section: + description: "Name of the dict in config file" + required: true + type: string + repo-file: + default: ".github/repo-list.txt" + description: | + File with repository names. One per line. + If not provided, the action will be triggered for all repositories in the organization. + required: false + type: string +permissions: + contents: read + statuses: read +jobs: + setup_jobs: + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.setup_matrix.outputs.matrix }} + config: ${{ steps.setup_matrix.outputs.config }} + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + with: + persist-credentials: false + + - name: Set up jobs + id: setup_matrix + env: + REPO_NAMES: ${{ inputs.repos }} + CONFIG_FILE: ${{ inputs.config-file }} + SECTION: ${{ inputs.section }} + REPO_FILE: ${{ inputs.repo-file }} + run: | + set -euo pipefail + + # if [[ -n "$REPO_FILE" && -f "$REPO_FILE" ]]; then + # FILE_REPOS=$(grep -vE '^\s*#' "$REPO_FILE" | tr '\n' ',' | sed 's/,$//') + # if [[ -n "$REPO_NAMES" ]]; then + # REPO_NAMES="$REPO_NAMES,$FILE_REPOS" + # else + # REPO_NAMES="$FILE_REPOS" + # fi + # fi + + if [[ -n "$REPO_NAMES" ]]; then + JSON_MATRIX=$(jq -c -n --arg in_str "$REPO_NAMES" '$in_str | split(",")') + echo "matrix=$JSON_MATRIX" + echo "matrix=$JSON_MATRIX" >> $GITHUB_OUTPUT + else + echo "matrix=[\"\"]" + echo "matrix=[\"\"]" >> $GITHUB_OUTPUT + fi + + if [[ -f "$CONFIG_FILE" ]]; then + wget -q https://github.com/mikefarah/yq/releases/download/v4.34.1/yq_linux_amd64 -O yq + chmod +x yq + sudo mv yq /usr/local/bin/yq + + if [[ -n "$SECTION" ]]; then + settings=$(yq eval ".$SECTION" "$CONFIG_FILE" -o=json | jq -c '{settings: .}') + else + echo "::error::Config file section not specified!" + echo "[ERROR]: Config file section not specified!" >> $GITHUB_STEP_SUMMARY + exit 1 + fi + + echo "config=$settings" >> $GITHUB_OUTPUT + else + echo "::error::Config file '$CONFIG_FILE' not found." + echo "[ERROR]: Config file '$CONFIG_FILE' not found." >> $GITHUB_STEP_SUMMARY + exit 1 + fi + + replicate_files: + needs: setup_jobs + permissions: + pull-requests: write + + name: Replicating files + strategy: + fail-fast: false + matrix: + repo: ${{ fromJson(needs.setup_jobs.outputs.matrix) }} + max-parallel: 10 + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + with: + persist-credentials: false + + - name: Replicating files + uses: borislavr/manage-files-in-multiple-repositories@1a30789fb0ff451240b9497fc92f4ea8e969ce03 #v2.2.1 + with: + github_token: "${{ secrets.GH_ACCESS_TOKEN }}" + exclude_private: true + exclude_forked: false + committer_username: borislavr + bot_branch_name: ${{ fromJson(needs.setup_jobs.outputs.config).settings.bot_branch_name || 'broadcast-files' }} + patterns_to_include: ${{ fromJson(needs.setup_jobs.outputs.config).settings.patterns_to_include || '' }} + topics_to_include: ${{ fromJson(needs.setup_jobs.outputs.config).settings.topics_to_include || '' }} + destination: ${{ fromJson(needs.setup_jobs.outputs.config).settings.destination || '.' }} + commit_message: ${{ fromJson(needs.setup_jobs.outputs.config).settings.commit_message || 'broadcasted files' }} + repo_name: ${{ matrix.repo }} + patterns_to_ignore: ${{ fromJson(needs.setup_jobs.outputs.config).settings.patterns_to_ignore || '' }} + patterns_to_remove: ${{ fromJson(needs.setup_jobs.outputs.config).settings.patterns_to_remove || '' }} + repos_to_ignore: ${{ fromJson(needs.setup_jobs.outputs.config).settings.repos_to_ignore || '' }} diff --git a/.github/bug_report.yml b/.github/bug_report.yml new file mode 100644 index 0000000..33bfc2a --- /dev/null +++ b/.github/bug_report.yml @@ -0,0 +1,52 @@ +name: Bug report +description: Create a report to help us improve +labels: [bug] +title: "[Bug]: " +projects: ["Netcracker/13"] +type: Bug +body: + - type: textarea + id: describe-the-bug + attributes: + label: Describe the bug + description: | + A clear and concise description of what the bug is. + placeholder: | + When I perform `use case` I expect `expected result` while the `actual result` is different. + validations: + required: true + - type: textarea + id: to-reproduce + attributes: + label: To Reproduce + description: | + Steps to reproduce the behavior. + If reproducing an issue requires some specific configuration file, please paste it here. + placeholder: | + Steps to reproduce the behavior. + validations: + required: true + - type: textarea + id: version + attributes: + label: Version + description: | + Version of the related components + validations: + required: false + - type: textarea + id: logs + attributes: + label: Logs + description: | + Check if any warnings or errors if relevant + validations: + required: false + - type: textarea + id: additional-info + attributes: + label: Additional information + placeholder: | + Additional information that doesn't fit elsewhere + validations: + required: false diff --git a/.github/cdxgen.md b/.github/cdxgen.md new file mode 100644 index 0000000..49b8cd0 --- /dev/null +++ b/.github/cdxgen.md @@ -0,0 +1,83 @@ +# CDXGen + +## Overview + +The CDXGen workflow generates SBOM (Software Bill of Materials) files for the repository and vulnerability scan reports using CycloneDX. The workflow runs on push to the main branch and can also be triggered manually. + +## Trigger + +This workflow is triggered when: +- Code is pushed to the `main` branch +- Manually via `workflow_dispatch` with optional input parameters + +## Workflow Details + +### Jobs + +#### `cdxgen` +- **Runner**: `ubuntu-latest` +- **Purpose**: Generates CycloneDX SBOM and vulnerability reports + +#### `deploy-pages` (Conditional) +- **Runner**: `ubuntu-latest` +- **Purpose**: Deploys the generated report to GitHub Pages +- **Condition**: Only runs when `generate_cdx_report` input is true + +### Steps + +#### cdxgen Job +1. **cdxgen** + - Uses `netcracker/qubership-workflow-hub/actions/cdxgen@v1.0.4` + - Generates SBOM and vulnerability reports + - Accepts `generate_cdx_report` input parameter + +#### deploy-pages Job +1. **Deploy to GitHub Pages** + - Uses `actions/deploy-pages@v4` + - Deploys the generated report to GitHub Pages + - Requires `id-token: write` and `pages: write` permissions + +2. **Summary** + - Outputs the GitHub Pages URL for the CycloneDX report + +## Configuration + +### Input Parameters (Manual Trigger) +- `generate_cdx_report` (boolean, optional): Whether to generate CycloneDX report and deploy to GitHub Pages + +### Permissions +- `contents: read` - For reading repository contents +- `id-token: write` - For GitHub Pages deployment (conditional) +- `pages: write` - For GitHub Pages deployment (conditional) + +### Environment +- `github-pages` - For GitHub Pages deployment + +## Supported File Patterns +- `*/**/go.mod` - Go modules +- `*/**/pom.xml` - Maven projects +- `*/**/requirements.txt` - Python requirements +- `*/**/Dockerfile` - Docker containers +- `*/**/pyproject.toml` - Python projects + +## Usage + +This workflow is particularly useful for: +- Generating SBOM files for compliance and security audits +- Identifying vulnerabilities in dependencies +- Maintaining an up-to-date inventory of software components +- Deploying vulnerability reports to GitHub Pages for easy access + +## Categories +- Go +- Maven +- Python +- Docker +- Automation +- Utilities + +## Labels +- sbom +- security +- vulnerability-scan +- cyclonedx diff --git a/.github/cdxgen.properties.json b/.github/cdxgen.properties.json new file mode 100644 index 0000000..397088b --- /dev/null +++ b/.github/cdxgen.properties.json @@ -0,0 +1,19 @@ +{ + "name": "Qubership CDXGen", + "description": "Generate SBOM file by CDXGen and vulnerability Scan report by CyclonDX.", + "categories": [ + "Go", + "Maven", + "Pthon", + "Docker", + "Automation", + "utilities" + ], + "filePatterns": [ + "*/**/go.mod", + "*/**/pom.xml", + "*/**/requirements.txt", + "*/**/Dockerfile", + "*/**/pyproject.toml" + ] +} diff --git a/.github/cdxgen.yaml b/.github/cdxgen.yaml new file mode 100644 index 0000000..0f3e10b --- /dev/null +++ b/.github/cdxgen.yaml @@ -0,0 +1,46 @@ +--- + +# The workflow will generate the SBOM file for the repository +# and vulerability scan report for the SBOM file using CycloneDX +# The workflow will run on push to main branch and manually triggered workflows +# The results will be stored in the action artifacts + +name: 'CDXGen' +on: + workflow_dispatch: + inputs: + generate_cdx_report: + description: "Generate CycloneDX report" + required: false + default: false + type: boolean + push: + branches: + - 'main' +permissions: + contents: read +jobs: + cdxgen: + runs-on: ubuntu-latest + steps: + - name: "cdxgen" + uses: netcracker/qubership-workflow-hub/actions/cdxgen@v2.0.0 + with: + generate_cdx_report: ${{ github.event.inputs.generate_cdx_report }} + deploy-pages: + if: ${{ github.event.inputs.generate_cdx_report }} + permissions: + id-token: write + pages: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: cdxgen + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5 + - name: "Summary" + run: | + echo "${{ steps.deployment.outputs.page_url }}cyclondx-report" >> $GITHUB_STEP_SUMMARY diff --git a/.github/check-license.md b/.github/check-license.md new file mode 100644 index 0000000..c370f43 --- /dev/null +++ b/.github/check-license.md @@ -0,0 +1,13 @@ +# GO Project Check Modules License + +The workflow will check licenses of all dependencies if they are in scope of allowlist. + +> More info about used tool can be found here [wwhrd](https://github.com/frapposelli/wwhrd) + +## Step 1: Create GO Project Check Modules License workflow + +Copy the [prepared file](https://github.com/Netcracker/.github/blob/main/workflow-templates/check-license.yaml) into `.github/workflows` directory of your repository. + +## Step 2: Create Configuration File + +Copy the [prepared file](https://github.com/Netcracker/.github/blob/main/config/examples/.wwhrd.yml) into root directory of your repository. diff --git a/.github/check-license.properties.json b/.github/check-license.properties.json new file mode 100644 index 0000000..05705d4 --- /dev/null +++ b/.github/check-license.properties.json @@ -0,0 +1,12 @@ +{ + "name": "Qubership Check Go Modules Licenses", + "description": "Check Go Modules Licenses workflow template.", + "categories": [ + "Go", + "Automation", + "utilities" + ], + "filePatterns": [ + "*/**/go.mod" + ] +} diff --git a/.github/check-license.yaml b/.github/check-license.yaml new file mode 100644 index 0000000..59ff143 --- /dev/null +++ b/.github/check-license.yaml @@ -0,0 +1,20 @@ +--- + +# This workflow will check the licenses of the go modules in the repository +# The workflow needs configuration in the .wwhrd.yml file in the root of repository. +# The example file can be found there: +# https://github.com/netcracker/qubership-workflow-hub/blob/main/docs/examples/.wwhrd.yml +# It will fail if any of the modules have a license that is not allowed +# It will also fail if any of the modules do not have a license +# It will pass if all modules have a license that is allowed + +name: Check Go Modules Licenses +on: + push: {} + +permissions: + contents: read + +jobs: + check-license: + uses: netcracker/qubership-workflow-hub/.github/workflows/go-check-license.yaml@v2.0.0 diff --git a/.github/cla.md b/.github/cla.md new file mode 100644 index 0000000..fc2a781 --- /dev/null +++ b/.github/cla.md @@ -0,0 +1,9 @@ +# CLA workflow + +The action for [CLA](./CLA/cla.md) "signing" for contributors. + +> More info about underlying GitHub Action can be found here [contributor-assistant](https://github.com/contributor-assistant/github-action) + +**To add the CLA signing into your repository** just copy the [prepared file](https://github.com/Netcracker/.github/blob/main/workflow-templates/cla.yaml) into `.github/workflows` directory of your repository. + +The `CLA_ACCESS_TOKEN` used in the workflow is defined on organization level then you can use it in any Netcracker/\* repository. diff --git a/.github/cla.properties.json b/.github/cla.properties.json new file mode 100644 index 0000000..04752a8 --- /dev/null +++ b/.github/cla.properties.json @@ -0,0 +1,8 @@ +{ + "name": "Qubership CLA Assistant", + "description": "CLA Assistant workflow template. It can be used to automatically check if the PR author has signed the CLA.", + "categories": [ + "Automation" + ], + "labels": [ "preview"] +} diff --git a/.github/cla.yaml b/.github/cla.yaml new file mode 100644 index 0000000..3ee48eb --- /dev/null +++ b/.github/cla.yaml @@ -0,0 +1,34 @@ +--- +name: CLA Assistant +on: + issue_comment: + types: [created] + pull_request_target: + types: [opened, closed, synchronize] + +permissions: + contents: read + +jobs: + CLAAssistant: + permissions: + actions: write + contents: write + pull-requests: write + statuses: write + runs-on: ubuntu-latest + steps: + - name: "CLA Assistant" + if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' + uses: contributor-assistant/github-action@ca4a40a7d1004f18d9960b404b97e5f30a505a08 #v2.6.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PERSONAL_ACCESS_TOKEN: ${{ secrets.CLA_ACCESS_TOKEN }} + with: + path-to-signatures: 'signatures/version1/cla.json' + path-to-document: 'https://github.com/Netcracker/qubership-github-workflows/blob/main/CLA/cla.md' + # branch should not be protected + branch: 'main' + allowlist: NetcrackerCLPLCI,web-flow,bot* + remote-repository-name: cla-storage + remote-organization-name: Netcracker diff --git a/.github/cleanup-old-docker-container.md b/.github/cleanup-old-docker-container.md new file mode 100644 index 0000000..b0711c3 --- /dev/null +++ b/.github/cleanup-old-docker-container.md @@ -0,0 +1,79 @@ +# Cleanup Old Docker Container Versions + +## Overview + +The Cleanup Old Docker Container Versions workflow is designed to clean up old Docker container versions in a GitHub repository. It helps maintain repository hygiene by removing outdated container images based on configurable criteria. + +## Trigger + +This workflow is triggered when: +- Scheduled weekly on Sunday at midnight (cron: "0 0 * * 0") +- Manually via `workflow_dispatch` with customizable input parameters + +## Workflow Details + +### Jobs + +#### `cleanup` +- **Runner**: `ubuntu-latest` +- **Purpose**: Cleans up old Docker container versions from GitHub Container Registry (GHCR) + +### Steps + +1. **Summary** + - Displays workflow execution details including: + - Event type + - Actor (who triggered the workflow) + - Threshold days for cleanup + - Included/excluded tag patterns + - Dry-run mode status + +2. **Login to GHCR** + - Uses `docker/login-action@v3` + - Authenticates with GitHub Container Registry + - Requires `GH_RWD_PACKAGE_TOKEN` secret + +3. **Run Container Package Cleanup Action** + - Uses `netcracker/qubership-workflow-hub/actions/container-package-cleanup@v1.0.4` + - Performs the actual cleanup operation + - Requires `GH_ACCESS_TOKEN` secret + +## Configuration + +### Input Parameters (Manual Trigger) +- `threshold-days` (string, optional): Number of days to keep container versions (default: "7") +- `included-tags` (string, optional): Tags to include for deletion (default: "") +- `excluded-tags` (string, optional): Tags to exclude from deletion (default: "release*") +- `dry-run` (string, optional): Enable dry-run mode (default: "false") + +### Required Secrets +- `GH_RWD_PACKAGE_TOKEN`: Token for GitHub Container Registry authentication +- `GH_ACCESS_TOKEN`: Token for package cleanup operations + +### Permissions +- `contents: read` - For reading repository contents + +## Usage + +This workflow is particularly useful for: +- Maintaining clean GitHub Container Registry repositories +- Removing outdated development and test images +- Preserving important release tags +- Testing cleanup operations in dry-run mode before execution + +## Safety Features + +- **Dry-run mode**: Test cleanup operations without actually deleting images +- **Tag exclusions**: Protect important tags (like releases) from deletion +- **Configurable thresholds**: Set custom retention periods +- **Scheduled execution**: Automated cleanup without manual intervention + +## Categories +- CI/CD +- Automation + +## Labels +- cleanup +- docker +- maven +- ghcr diff --git a/.github/cleanup-old-docker-container.properties.json b/.github/cleanup-old-docker-container.properties.json new file mode 100644 index 0000000..1d2aa52 --- /dev/null +++ b/.github/cleanup-old-docker-container.properties.json @@ -0,0 +1,14 @@ +{ + "name": "Qubership Cleanup Old docker containers.", + "description": "A workflow template for cleaning-up old docker containers in GitHub packages.", + "categories": [ + "CI/CD", + "Automation" + ], + "labels": [ + "cleanup", + "docker", + "maven", + "ghcr" + ] +} diff --git a/.github/cleanup-old-docker-container.yaml b/.github/cleanup-old-docker-container.yaml new file mode 100644 index 0000000..00b524a --- /dev/null +++ b/.github/cleanup-old-docker-container.yaml @@ -0,0 +1,58 @@ +--- +# This workflow is designed to clean up old Docker container versions in a GitHub repository. +name: Cleanup Old Docker Container Versions +run-name: "${{ github.event_name }} - ${{ github.actor }}" +on: + schedule: + - cron: "0 0 * * 0" # Runs weekly on Sunday at midnight + workflow_dispatch: + inputs: + threshold-days: + description: "Number of days to keep container versions" + required: false + default: "7" + included-tags: + description: "Tags to include for deletion" + required: false + default: "" + excluded-tags: + description: "Tags to exclude from deletion" + required: false + default: "release*" + dry-run: + description: "Enable dry-run mode" + required: false + default: "false" +permissions: + contents: read + +jobs: + cleanup: + runs-on: ubuntu-latest + + steps: + - name: "Summary" + run: | + echo "**Event**: ${{ github.event_name }}" + echo "**Actor**: ${{ github.actor }}" + echo "**Threshold days**: ${{ github.event.inputs.threshold-days || 8 }}" + echo "**Included tags**: ${{ github.event.inputs.included-tags || 'dev*' }}" + echo "**Excluded tags**: ${{ github.event.inputs.excluded-tags || 'release*' }}" + echo "**Dry-run**: ${{ github.event.inputs.dry-run || 'false' }}" + + - name: Login to GHCR + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GH_RWD_PACKAGE_TOKEN }} + + - name: Run Container Package Cleanup Action + uses: netcracker/qubership-workflow-hub/actions/container-package-cleanup@9319676b7d20b423a2e0943a0ac08da07d615998 #v1.0.6 + with: + threshold-days: ${{ github.event.inputs.threshold-days || 8 }} + included-tags: ${{ github.event.inputs.included-tags || 'dev*' }} + excluded-tags: ${{ github.event.inputs.excluded-tags || 'release*' }} + dry-run: ${{ github.event.inputs.dry-run || 'false' }} + env: + PACKAGE_TOKEN: ${{ secrets.GH_ACCESS_TOKEN }} diff --git a/.github/commit-msg.sample b/.github/commit-msg.sample new file mode 100755 index 0000000..b58d118 --- /dev/null +++ b/.github/commit-msg.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, rename this file to "commit-msg". + +# Uncomment the below to add a Signed-off-by line to the message. +# Doing this in a hook is a bad idea in general, but the prepare-commit-msg +# hook is more suited to it. +# +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/.github/config b/.github/config new file mode 100644 index 0000000..1daf951 --- /dev/null +++ b/.github/config @@ -0,0 +1,13 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true +[remote "origin"] + url = https://github.com/Netcracker/.github + fetch = +refs/heads/*:refs/remotes/origin/* +[gc] + auto = 0 +[branch "main"] + remote = origin + merge = refs/heads/main diff --git a/.github/config.worktree b/.github/config.worktree new file mode 100644 index 0000000..8274832 --- /dev/null +++ b/.github/config.worktree @@ -0,0 +1,5 @@ +[core] + sparseCheckout = false + sparseCheckoutCone = false +[index] + sparse = false diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..cdd45d9 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,149 @@ +# Netcracker/.github Repository - GitHub Workflow Templates + +The Netcracker/.github repository is a special GitHub organization repository that provides standardized CI/CD workflow templates, configuration files, and documentation for repositories across the Netcracker/Qubership organization. This is a template and configuration repository, not a traditional software project. + +Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here. + +## Working Effectively + +### Essential Setup and Validation +- Bootstrap the repository validation tools: + - `npm install markdownlint-cli2 markdown-link-check --no-save` -- installs validation tools locally (7 seconds) + - NEVER CANCEL: Validation tools install takes 5-10 seconds. Set timeout to 30+ seconds. + - Add `node_modules/` to `.gitignore` to avoid committing dependencies + +### Core Validation Commands (The "Build" Process) +- **YAML Linting**: `yamllint -c .github/linters/.yaml-lint.yml .` -- validates all YAML files (0.5 seconds) +- **Markdown Linting**: `npx markdownlint-cli2 --config .github/linters/.markdownlint.json "**/*.md"` -- validates markdown files (3 seconds) +- **Link Checking**: `npx markdown-link-check README.md` -- validates links in README (1.5 seconds) +- **Full Validation**: Run all three commands sequentially -- completes in under 10 seconds total +- NEVER CANCEL: All validation commands complete in under 10 seconds. Set timeout to 30+ seconds. + +### Common Validation Issues and Solutions +- YAML files may have indentation warnings - these are style issues, not critical errors +- Markdown files often have line length violations (120 char limit) - fix by breaking long lines +- Some workflow templates intentionally have YAML validation issues - document but don't fix unless requested + +## Repository Structure and Navigation + +### Key Directories +- **`workflow-templates/`**: GitHub Actions workflow templates for various languages and use cases + - Contains 30+ templates including Maven, NPM, Python, Go, Docker workflows + - Each template has corresponding `.properties.json` file for GitHub's template system +- **`config/examples/`**: Example configuration files for various tools and workflows + - Includes examples for Docker builds, release drafting, PR labeling, etc. +- **`docs/workflows/`**: Detailed documentation for each workflow template + - One markdown file per workflow explaining usage, requirements, and configuration +- **`.github/`**: Organization-level GitHub configuration + - Workflow files that run on this repository itself + - Linter configurations in `.github/linters/` + - Issue templates, security policies, contributor guidelines + +### Important Files +- **`README.md`**: Main documentation listing all available workflow templates +- **`.github/linters/`**: Linter configuration files + - `.yaml-lint.yml`: YAML validation rules + - `.markdownlint.json`: Markdown validation rules + - `.checkov.yaml`: Security scanning configuration +- **`workflow-templates/*.yaml`**: The actual workflow template files +- **`config/examples/`**: Configuration file examples for copying to other repositories + +## Validation Scenarios + +### After Making Changes to Workflow Templates +1. **Always run full validation**: `yamllint -c .github/linters/.yaml-lint.yml . && npx markdownlint-cli2 --config .github/linters/.markdownlint.json "*.md"` +2. **Test specific workflow syntax**: YAML linting will catch most GitHub Actions syntax issues +3. **Validate documentation**: Check that any new templates have corresponding documentation in `docs/workflows/` +4. **Link validation**: Run `npx markdown-link-check README.md` to ensure all links work + +### After Making Changes to Documentation +1. **Markdown validation**: `npx markdownlint-cli2 --config .github/linters/.markdownlint.json "**/*.md"` +2. **Link checking**: Test links with `npx markdown-link-check [filename].md` +3. **Table of contents sync**: Ensure README.md table matches actual available workflows + +### Manual Testing Scenarios +- **Workflow Template Usage**: Copy a template to a test repository and verify it works +- **Configuration Examples**: Validate example config files are syntactically correct +- **Documentation Accuracy**: Verify workflow documentation matches actual template implementation + +## Common Tasks + +### Adding a New Workflow Template +1. Create workflow YAML file in `workflow-templates/` +2. Create corresponding `.properties.json` file for GitHub template system +3. Add documentation file in `docs/workflows/` +4. Update README.md table with new workflow +5. Add example configuration files to `config/examples/` if needed +6. Run validation: `yamllint -c .github/linters/.yaml-lint.yml workflow-templates/[new-file].yaml` + +### Updating Existing Templates +1. Edit workflow file in `workflow-templates/` +2. Update corresponding documentation in `docs/workflows/` +3. Update README.md if description changes +4. Run full validation to ensure no syntax errors + +### Configuration File Management +- Example configurations in `config/examples/` should be valid and current +- Always validate JSON/YAML syntax when updating config examples +- Test configurations with actual workflows when possible + +## Repository Characteristics + +- **No Traditional Build Process**: This repository contains templates and documentation, not compiled code +- **Validation is the "Build"**: The closest equivalent to building is running the linting and validation tools +- **Fast Operations**: All validation completes in under 10 seconds +- **GitHub Actions Focus**: Primary purpose is providing reusable GitHub Actions workflows +- **Multi-Language Support**: Templates support Java/Maven, Node.js/NPM, Python, Go, Docker, and more +- **Organization-Wide Impact**: Changes here affect CI/CD across all Netcracker repositories + +## Time Expectations + +- **Tool Installation**: 5-10 seconds for npm packages +- **YAML Validation**: 0.5 seconds for entire repository +- **Markdown Validation**: 2-3 seconds for all files +- **Link Checking**: 1-2 seconds per file +- **Full Validation Suite**: Under 10 seconds total +- NEVER CANCEL: All operations complete quickly. Use 30+ second timeouts to be safe. + +## Known Issues and Limitations + +- Some workflow templates intentionally have YAML style warnings (indentation) +- Link checking may fail on external URLs due to network restrictions +- Super-linter Docker image may not be accessible in all environments +- ActionLint tool installation may fail due to network restrictions +- Node modules should never be committed (use .gitignore) + +## Reference Information + +### Repository Root Contents +``` +.editorconfig # Editor configuration +.gitattributes # Git file handling rules +.github/ # Organization GitHub config and workflows +CODEOWNERS # Code review assignments +LICENSE # Apache 2.0 license +README.md # Main documentation +config/ # Configuration examples and tools +docs/ # Workflow documentation +workflow-templates/ # GitHub Actions workflow templates +``` + +### Essential Commands Reference +```bash +# Install validation tools (7 seconds) +npm install markdownlint-cli2 markdown-link-check --no-save + +# Validate YAML files (0.5 seconds) +yamllint -c .github/linters/.yaml-lint.yml . + +# Validate Markdown files (3 seconds) +npx markdownlint-cli2 --config .github/linters/.markdownlint.json "**/*.md" + +# Check links (1.5 seconds) +npx markdown-link-check README.md + +# Full validation sequence (under 10 seconds) +yamllint -c .github/linters/.yaml-lint.yml . && \ +npx markdownlint-cli2 --config .github/linters/.markdownlint.json "*.md" && \ +npx markdown-link-check README.md +``` \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..1b5553e --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,49 @@ +--- +version: 2 +updates: + - package-ecosystem: maven + directory: / + schedule: + interval: weekly + groups: + spring: + patterns: + - org.springframework.* + quarkus: + patterns: + - io.quarkus.* + qubership: + patterns: + - org.qubership.* + ignore: + - dependency-name: io.quarkus.* + versions: + - '[3.16.0,]' + - dependency-name: 'org.apache.maven.plugins:maven-surefire-plugin' + versions: + - '[3.3.0,]' + - dependency-name: 'io.smallrye:jandex-maven-plugin' + versions: + - '[3.2.0,]' + - dependency-name: 'org.apache.maven.plugins:maven-source-plugin' + versions: + - '[3.3.0,]' + - dependency-name: 'org.apache.maven.plugins:maven-compiler-plugin' + versions: + - '[3.13.0,]' + - dependency-name: 'org.junit.jupiter:junit-jupiter.*' + versions: + - '[5.11.0,]' + - package-ecosystem: "gomod" + directories: + - /** + schedule: + interval: weekly + groups: + qubership: + patterns: + - github.com/netcracker/* + - package-ecosystem: docker + directory: / + schedule: + interval: weekly diff --git a/.github/dependency-review.md b/.github/dependency-review.md new file mode 100644 index 0000000..2019814 --- /dev/null +++ b/.github/dependency-review.md @@ -0,0 +1,77 @@ +# Dependency Review + +## Overview + +The Dependency Review workflow performs comprehensive dependency analysis on pull requests and can also be triggered manually. It checks for vulnerabilities, license compliance, and provides OpenSSF Scorecard information to ensure the security and compliance of dependencies. + +## Trigger + +This workflow is triggered when: +- A pull request is created or updated +- Manually via `workflow_dispatch` + +## Workflow Details + +### Jobs + +#### `dependency-review` +- **Runner**: `ubuntu-latest` +- **Purpose**: Performs dependency review analysis with different configurations based on trigger type + +### Steps + +1. **Checkout Repository** + - Uses `actions/checkout@v4` + - Fetches complete repository history (`fetch-depth: 0`) + +2. **Get the first commit SHA** (Manual trigger only) + - Runs only when triggered manually via `workflow_dispatch` + - Identifies the first commit in the repository history + - Sets `first_commit_sha` environment variable + +3. **Dependency Review (manual)** + - Runs only when triggered manually via `workflow_dispatch` + - Uses `actions/dependency-review-action@v4` + - Compares from the first commit to the current reference + - Enables all checks with warning-only mode + +4. **Dependency Review (pull_request)** + - Runs only when triggered by pull request events + - Uses `actions/dependency-review-action@v4` + - Compares the base and head of the pull request + - Enables all checks with standard enforcement + +## Configuration + +### Features Enabled +- **OpenSSF Scorecard**: Shows security scorecard information +- **Vulnerability Check**: Identifies known security vulnerabilities +- **License Check**: Validates license compliance +- **Warning Mode**: For manual triggers, issues warnings instead of failing the workflow + +### Permissions +- `contents: read` - For reading repository contents and dependency information + +## Usage + +This workflow is particularly useful for: +- Ensuring dependency security in pull requests +- Identifying vulnerable dependencies before they are merged +- Checking license compliance of dependencies +- Getting comprehensive dependency analysis for the entire repository history + +## Security Features + +- **Vulnerability scanning**: Identifies known CVEs in dependencies +- **License compliance**: Ensures dependencies meet license requirements +- **OpenSSF Scorecard**: Provides security scoring for dependencies +- **Comprehensive analysis**: Reviews all dependencies in the repository + +## Categories +- CI/CD +- Automation + +## Labels +- security +- dependencies +- compliance diff --git a/.github/dependency-review.properties.json b/.github/dependency-review.properties.json new file mode 100644 index 0000000..2872483 --- /dev/null +++ b/.github/dependency-review.properties.json @@ -0,0 +1,8 @@ +{ + "name": "Qubership Dependency review.", + "description": "A workflow template for dependency review.", + "categories": [ + "CI/CD", + "Automation" + ] +} diff --git a/.github/dependency-review.yaml b/.github/dependency-review.yaml new file mode 100644 index 0000000..b9c30d4 --- /dev/null +++ b/.github/dependency-review.yaml @@ -0,0 +1,38 @@ +--- + +name: 'Dependency Review' +on: [pull_request, workflow_dispatch] + +permissions: + contents: read + +jobs: + dependency-review: + runs-on: ubuntu-latest + steps: + - name: 'Checkout Repository' + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + fetch-depth: 0 + persist-credentials: false + - name: "Get the first commit SHA" + if: github.event_name == 'workflow_dispatch' + id: first-commit + run: echo "first_commit_sha=$(git rev-list --max-parents=0 HEAD)" >> $GITHUB_ENV + - name: 'Dependency Review (manual)' + if: github.event_name == 'workflow_dispatch' + uses: actions/dependency-review-action@595b5aeba73380359d98a5e087f648dbb0edce1b # v4.7.3 + with: + base-ref: ${{ env.first_commit_sha }} + head-ref: ${{ github.ref }} + show-openssf-scorecard: true + vulnerability-check: true + license-check: true + warn-only: true + - name: 'Dependency Review (pull_request)' + if: github.event_name == 'pull_request' + uses: actions/dependency-review-action@595b5aeba73380359d98a5e087f648dbb0edce1b # v4.7.3 + with: + show-openssf-scorecard: true + vulnerability-check: true + license-check: true diff --git a/.github/description b/.github/description new file mode 100755 index 0000000..498b267 --- /dev/null +++ b/.github/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/.github/dev-docker-build.md b/.github/dev-docker-build.md new file mode 100644 index 0000000..9da6367 --- /dev/null +++ b/.github/dev-docker-build.md @@ -0,0 +1,84 @@ +# Dev Docker Build + +## Overview + +The Dev Docker Build workflow is designed for building and publishing Docker images during development. It dynamically generates artifact names, prepares tags, and supports a dry-run mode for testing. The workflow is triggered manually and allows customization of artifact names and tags. + +## Trigger + +This workflow is triggered manually via `workflow_dispatch` with customizable input parameters. + +## Workflow Details + +### Jobs + +#### `perform-version` +- **Runner**: `ubuntu-latest` +- **Purpose**: Generates metadata and prepares tags for the Docker build +- **Outputs**: + - `metadata`: Generated metadata result + - `tags`: Prepared tags for the Docker image + +#### `docker-build` +- **Runner**: Uses reusable workflow +- **Purpose**: Builds and publishes the Docker image +- **Dependencies**: Requires `perform-version` job completion + +### Steps + +#### perform-version Job +1. **Checkout code** + - Uses `actions/checkout@v2` + - Checks out the repository code + +2. **Create name** + - Uses `netcracker/qubership-workflow-hub/actions/metadata-action@v1.0.4` + - Generates metadata based on [`.github/metadata-config.yml`](../../config/examples/metadata-config.yml) configuration + +3. **Prepare tags** + - Combines base tag from metadata with optional extra tags + - Handles cases where extra tags are provided or not + +4. **Summary step** + - Outputs metadata and tags information to workflow summary + +#### docker-build Job +- Uses reusable workflow `netcracker/qubership-workflow-hub/.github/workflows/docker-publish.yml@v1.0.3` +- Passes the generated metadata and tags to the reusable workflow + +## Configuration + +### Input Parameters +- `artifact-name` (string, optional): Custom artifact name (defaults to repository name if not provided) +- `tags` (string, optional): Additional tags for the Docker image +- `dry-run` (boolean, optional): Enable dry-run mode for testing (default: false) + +### Required Files +- [`.github/metadata-config.yml`](../../config/examples/metadata-config.yml): Configuration file for metadata generation + +### Permissions +- `contents: read` - For reading repository contents +- `packages: write` - For publishing Docker images (inherited from reusable workflow) + +## Usage + +This workflow is particularly useful for: +- Development builds of Docker images +- Testing Docker build configurations +- Customizing artifact names and tags +- Dry-run testing before actual builds + +## Features + +- **Dynamic metadata generation**: Automatically generates appropriate names and versions +- **Flexible tagging**: Supports custom tags in addition to generated ones +- **Dry-run support**: Test builds without actually publishing images +- **Reusable workflow integration**: Leverages the established Docker publish workflow + +## Categories +- CI/CD +- Automation + +## Labels +- dev +- docker diff --git a/.github/dev-docker-build.properties.json b/.github/dev-docker-build.properties.json new file mode 100644 index 0000000..e40b136 --- /dev/null +++ b/.github/dev-docker-build.properties.json @@ -0,0 +1,12 @@ +{ + "name": "Qubership Dev Docker Build Workflow", + "description": "A workflow template for building and publishing Docker images. It dynamically generates artifact names, prepares tags, and supports a dry-run mode for testing. The workflow is triggered manually and allows customization of artifact names and tags.", + "categories": [ + "CI/CD", + "Automation" + ], + "labels": [ + "dev", + "docker" + ] +} diff --git a/.github/dev-docker-build.yml b/.github/dev-docker-build.yml new file mode 100644 index 0000000..68b53fb --- /dev/null +++ b/.github/dev-docker-build.yml @@ -0,0 +1,94 @@ +name: Dev Docker Build +run-name: "Dev build repository: ${{ github.ref_name }} #${{ github.run_number }}" + +on: + workflow_dispatch: + inputs: + custom-image-name: + description: 'Image name. If empty, use repository name' + required: false + default: '' + tags: + description: 'Tags' + required: false + type: string + default: '' + dry-run: + description: 'Dry run' + required: false + type: boolean + default: false + push: + branches: + - '**' + paths-ignore: + - '.github/**' + - 'docs/**' + - 'CODE-OF-CONDUCT.md' + - 'CONTRIBUTING.md' + - 'LICENSE' + - 'README.md' + - 'SECURITY.md' + pull_request: + branches: + - '**' + paths-ignore: + - '.github/**' + - 'docs/**' + - 'CODE-OF-CONDUCT.md' + - 'CONTRIBUTING.md' + - 'LICENSE' + - 'README.md' + - 'SECURITY.md' +permissions: + contents: read + +env: + PLATFORMS: linux/amd64,linux/arm64 + +jobs: + docker-build: + permissions: + packages: write + contents: read + outputs: + metadata: "${{ steps.metadata.outputs.result }}" + tags: "${{ steps.prepare_tags.outputs.tags }}" + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + + - name: Create name + uses: netcracker/qubership-workflow-hub/actions/metadata-action@9319676b7d20b423a2e0943a0ac08da07d615998 # v1.0.7 + id: metadata + + - name: Prepare tags + id: prepare_tags + run: | + BASE_TAG="${{ steps.metadata.outputs.result }}" + EXTRA_TAG="${{ github.event.inputs.tags }}" + if [ -n "$EXTRA_TAG" ]; then + TAGS="${BASE_TAG}, ${EXTRA_TAG}" + else + TAGS="${BASE_TAG}" + fi + echo "tags=${TAGS}" >> $GITHUB_OUTPUT + + - name: Summary step + run: | + echo "**Metadata:** ${{ steps.metadata.outputs.result }}" >> $GITHUB_STEP_SUMMARY + echo "**Tags:** ${{ steps.prepare_tags.outputs.tags }}" >> $GITHUB_STEP_SUMMARY + + - name: Build and Publish Docker Image + uses: netcracker/qubership-workflow-hub/actions/docker-action@9319676b7d20b423a2e0943a0ac08da07d615998 #v1.0.7 + with: + custom-image-name: ${{ github.event.inputs.custom-image-name || '' }} + platforms: ${{ env.PLATFORMS }} + checkout: "false" + tags: ${{ steps.prepare_tags.outputs.tags }} + dry-run: ${{ github.event.inputs.dry-run || 'false' }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/dev-mvn-docker-build.md b/.github/dev-mvn-docker-build.md new file mode 100644 index 0000000..4ec2187 --- /dev/null +++ b/.github/dev-mvn-docker-build.md @@ -0,0 +1,101 @@ +# Dev Mvn Docker Build + +## Overview + +The Dev Mvn Docker Build workflow is designed for development builds that combine Maven package building with Docker image creation. It automatically builds Maven packages with Java configuration, generates artifacts with dynamic naming and tags, and publishes Docker images. The workflow supports customizable Java version and dry-run mode. + +## Trigger + +This workflow is triggered manually via `workflow_dispatch` with customizable input parameters. + +## Workflow Details + +### Jobs + +#### `dev-build` +- **Runner**: Uses reusable workflow +- **Purpose**: Builds Maven packages and uploads artifacts +- **Uses**: `netcracker/qubership-workflow-hub/.github/workflows/maven-publish.yml@v1.0.7` + +#### `perform-version` +- **Runner**: `ubuntu-latest` +- **Purpose**: Generates metadata and prepares tags for the Docker build +- **Dependencies**: Requires `dev-build` job completion +- **Outputs**: + - `metadata`: Generated metadata result + - `tags`: Prepared tags for the Docker image + +#### `docker-build` +- **Runner**: Uses reusable workflow +- **Purpose**: Builds and publishes the Docker image +- **Dependencies**: Requires `perform-version` job completion +- **Uses**: `netcracker/qubership-workflow-hub/.github/workflows/docker-publish.yml@v1.0.7` + +### Steps + +#### dev-build Job +- Uses the Maven publish reusable workflow +- Configurable Maven command and Java version +- Uploads artifacts for use in Docker build + +#### perform-version Job +1. **Checkout code** + - Uses `actions/checkout@v2` + - Checks out the repository code + +2. **Create name** + - Uses `netcracker/qubership-workflow-hub/actions/metadata-action@v1.0.7` + - Generates metadata for naming and versioning + +3. **Prepare tags** + - Combines base tag from metadata with optional extra tags + - Handles cases where extra tags are provided or not + +4. **Summary step** + - Outputs metadata and tags information to workflow summary + +#### docker-build Job +- Uses the Docker publish reusable workflow +- Downloads artifacts from the Maven build +- Publishes Docker image with generated tags + +## Configuration + +### Input Parameters +- `maven-command` (string, optional): Maven command to execute (default: "--batch-mode package -Dgpg.skip=true") +- `artifact-name` (string, optional): Custom artifact name (defaults to repository name if not provided) +- `tags` (string, optional): Additional tags for the Docker image +- `java-version` (string, optional): Java version to use (default: "21") +- `dry-run` (boolean, optional): Enable dry-run mode for testing (default: false) + +### Required Secrets +- `GITHUB_TOKEN`: Token for Maven package operations + +### Permissions +- `contents: read` - For reading repository contents +- `packages: write` - For publishing Maven packages and Docker images + +## Usage + +This workflow is particularly useful for: +- Development builds that require both Maven and Docker +- Testing Maven builds with different Java versions +- Creating Docker images from Maven artifacts +- Customizing build parameters for development testing + +## Features + +- **Maven integration**: Builds Maven packages with configurable commands +- **Java version flexibility**: Supports different Java versions +- **Artifact management**: Uploads Maven artifacts for Docker builds +- **Dynamic metadata generation**: Automatically generates appropriate names and versions +- **Flexible tagging**: Supports custom tags in addition to generated ones +- **Dry-run support**: Test builds without actually publishing images + +## Categories +- CI/CD +- Automation + +## Labels +- dev +- docker diff --git a/.github/dev-mvn-docker-build.properties.json b/.github/dev-mvn-docker-build.properties.json new file mode 100644 index 0000000..3c87073 --- /dev/null +++ b/.github/dev-mvn-docker-build.properties.json @@ -0,0 +1,12 @@ +{ + "name": "Qubership Dev Mvn Build Workflow", + "description": "A workflow template for development builds. It automatically builds Maven packages with Java configuration, generates artifacts with dynamic naming and tags, and publishes Docker images. Supports customizable Java version and dry-run mode.", + "categories": [ + "CI/CD", + "Automation" + ], + "labels": [ + "dev", + "docker" + ] +} diff --git a/.github/dev-mvn-docker-build.yml b/.github/dev-mvn-docker-build.yml new file mode 100644 index 0000000..2dfed53 --- /dev/null +++ b/.github/dev-mvn-docker-build.yml @@ -0,0 +1,105 @@ +name: Dev Mvn Docker Build +run-name: "Dev build repository: ${{ github.ref_name }} #${{ github.run_number }}" + +on: + workflow_dispatch: + inputs: + maven-command: + description: 'Maven command' + required: false + type: string + default: "--batch-mode package -Dgpg.skip=true" + custom-image-name: + description: 'Custom image name' + required: false + default: '' + tags: + description: 'Tags' + required: false + type: string + default: '' + java-version: + description: 'Java version (e.g., 21)' + required: false + type: string + default: "21" + dry-run: + description: 'Dry run' + required: false + type: boolean + default: false + push: + branches: + - '**' + paths-ignore: + - '.github/**' + - 'docs/**' + - 'CODE-OF-CONDUCT.md' + - 'CONTRIBUTING.md' + - 'LICENSE' + - 'README.md' + - 'SECURITY.md' + pull_request: + branches: + - '**' + paths-ignore: + - '.github/**' + - 'docs/**' + - 'CODE-OF-CONDUCT.md' + - 'CONTRIBUTING.md' + - 'LICENSE' + - 'README.md' + - 'SECURITY.md' + +permissions: + contents: read + +jobs: + dev-build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: Checkout code + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + + - name: Maven build artifact + uses: netcracker/qubership-workflow-hub/actions/maven-snapshot-deploy@9319676b7d20b423a2e0943a0ac08da07d615998 #v1.0.6 + with: + maven-command: "${{ github.event.inputs.maven-command || '--batch-mode clean install -Dgpg.skip=true' }}" + java-version: ${{ github.event.inputs.java-version || '21' }} + + - name: Create name + uses: netcracker/qubership-workflow-hub/actions/metadata-action@main + id: metadata + + - name: Prepare tags + id: prepare_tags + run: | + BASE_TAG="${{ steps.metadata.outputs.result }}" + EXTRA_TAG="${{ github.event.inputs.tags }}" + if [ -n "$EXTRA_TAG" ]; then + TAGS="${BASE_TAG}, ${EXTRA_TAG}" + else + TAGS="${BASE_TAG}" + fi + echo "tags=${TAGS}" >> $GITHUB_OUTPUT + + - name: Summary step + run: | + echo "**Metadata:** ${{ steps.metadata.outputs.result }}" >> $GITHUB_STEP_SUMMARY + echo "**Tags:** ${{ steps.prepare_tags.outputs.tags }}" >> $GITHUB_STEP_SUMMARY + + - name: Build and Publish Docker Image + uses: netcracker/qubership-workflow-hub/actions/docker-action@9319676b7d20b423a2e0943a0ac08da07d615998 #v1.0.6 + with: + custom-image-name: ${{ github.event.inputs.custom-image-name || '' }} + platforms: ${{ env.PLATFORMS }} + checkout: "false" + tags: ${{ steps.prepare_tags.outputs.tags }} + dry-run: ${{ github.event.inputs.dry-run || 'false' }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/docker-build-config.json b/.github/docker-build-config.json new file mode 100644 index 0000000..45c7526 --- /dev/null +++ b/.github/docker-build-config.json @@ -0,0 +1,20 @@ +{ + "components": [ + { + "name": "qubership-zookeeper-integration-tests", + "file": "integration-tests/docker/Dockerfile", + "context": "integration-tests" + }, + { + "name": "qubership-zookeeper-operator", + "file": "Dockerfile", + "context": "." + }, + { + "name": "qubership-zookeeper-transfer", + "file": "docker-transfer/Dockerfile", + "context": "." + } + ], + "platforms": "linux/amd64,linux/arm64" +} diff --git a/.github/docker-release.md b/.github/docker-release.md new file mode 100644 index 0000000..cc091a6 --- /dev/null +++ b/.github/docker-release.md @@ -0,0 +1,34 @@ +# Docker Project Release Workflow + +Docker project release workflow is used to make a GitHub release and publish released artifacts into GitHub docker registry. +The workflow consists of several sequential jobs: + +1. Checks if the tag already exists. +2. Creates a new tag with name "v${version}. +3. [Builds and publishes a Docker image](https://github.com/Netcracker/qubership-workflow-hub/blob/main/docs/reusable/docker-publish.md). +4. Create GitHub release + +## Step 1: Docker release workflow + +Copy the [prepared file](https://github.com/Netcracker/.github/blob/main/workflow-templates/docker-release.yaml) into `.github/workflows` directory of your repository. + +This workflow is designed to be run manually. It has four input parameters on manual execution: + +- `Release version` -- a string represents version number of the release +- `Dry run` -- if selected the workflow will go through all the steps, but will not publish anything. + +## Step 2: Add configuration file for GitHub release + +Upload [prepared configuration file](https://github.com/Netcracker/.github/blob/main/config/examples/release-drafter-config.yml) to your repository in `.github` folder. You can customize it in future for your needs. + +## Some more info on input parameters + +The [underlying reusable workflow](https://github.com/Netcracker/qubership-workflow-hub/blob/main/.github/workflows/docker-publish.yml) accepts more input parameters then the release workflow. For simplicity the template workflow provides reasonable defaults which are suitable in most cases. The default usage scenario assumes the following conditions: + +- The resulting artifact name is the same as repository name +- Artifact built from tag name equal to `v${version}` +- There are no pre-built artifacts. It means that Dockerfile has a "build from sources" stage +- There is only one Dockerfile and it placed in the root of repository +- Build context for Dockerfile is `.` + +If the default case isn't your's -- please read [the detailed description](https://github.com/Netcracker/qubership-workflow-hub/blob/main/docs/reusable/docker-publish.md#detailed-description-of-variables) of the input parameters and customize them according to your needs. diff --git a/.github/exclude b/.github/exclude new file mode 100755 index 0000000..a5196d1 --- /dev/null +++ b/.github/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/.github/feature_request.yml b/.github/feature_request.yml new file mode 100644 index 0000000..ee28244 --- /dev/null +++ b/.github/feature_request.yml @@ -0,0 +1,46 @@ +name: Feature request +description: Suggest an idea for this project +labels: [enhancement] +title: "[Feat]: " +projects: ["Netcracker/13"] +type: Feature +body: + - type: textarea + id: describe-the-problem + attributes: + label: Is your feature request related to a problem? Please describe + description: | + A clear and concise description of what the problem is. + placeholder: | + Ex. I'm always frustrated when [...] + validations: + required: false + - type: textarea + id: describe-the-solution + attributes: + label: Describe the solution you'd like + description: | + A clear and concise description of what you want to happen. + validations: + required: true + - type: textarea + id: alternative-solutions + attributes: + label: Describe alternatives you've considered + description: | + A clear and concise description of any alternative solutions or features you've considered. + placeholder: | + I have tried to do `A`, but that doesn't solve a problem completely. + I have tried to do `A` and `B`, but implementing this would be better. + validations: + required: false + - type: textarea + id: feature-additional-info + attributes: + label: Additional information + description: | + Additional information which you consider helpful for implementing this feature. + placeholder: | + Add any other context or screenshots about the feature request here. + validations: + required: false diff --git a/.github/files_to_update.txt b/.github/files_to_update.txt new file mode 100644 index 0000000..d8a3441 --- /dev/null +++ b/.github/files_to_update.txt @@ -0,0 +1,15 @@ +helm-charts-release.yaml +link-checker.yaml +lint-test-chart.yaml +maven-release-v2.yaml +maven-release.yaml +maven-snapshot-deploy.yaml +npm-release.yaml +pr-conventional-commits.yaml +python-release.yaml +sbom-to-release.yaml +dev-docker-build.yml +dev-mvn-docker-build.yml +license-header.yml +pr-assigner.yml +scout-cves.yml diff --git a/.github/fsmonitor-watchman.sample b/.github/fsmonitor-watchman.sample new file mode 100755 index 0000000..23e856f --- /dev/null +++ b/.github/fsmonitor-watchman.sample @@ -0,0 +1,174 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use IPC::Open2; + +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to speed up detecting +# new and modified files. +# +# The hook is passed a version (currently 2) and last update token +# formatted as a string and outputs to stdout a new update token and +# all files that have been modified since the update token. Paths must +# be relative to the root of the working tree and separated by a single NUL. +# +# To enable this hook, rename this file to "query-watchman" and set +# 'git config core.fsmonitor .git/hooks/query-watchman' +# +my ($version, $last_update_token) = @ARGV; + +# Uncomment for debugging +# print STDERR "$0 $version $last_update_token\n"; + +# Check the hook interface version +if ($version ne 2) { + die "Unsupported query-fsmonitor hook version '$version'.\n" . + "Falling back to scanning...\n"; +} + +my $git_work_tree = get_working_dir(); + +my $retry = 1; + +my $json_pkg; +eval { + require JSON::XS; + $json_pkg = "JSON::XS"; + 1; +} or do { + require JSON::PP; + $json_pkg = "JSON::PP"; +}; + +launch_watchman(); + +sub launch_watchman { + my $o = watchman_query(); + if (is_work_tree_watched($o)) { + output_result($o->{clock}, @{$o->{files}}); + } +} + +sub output_result { + my ($clockid, @files) = @_; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # binmode $fh, ":utf8"; + # print $fh "$clockid\n@files\n"; + # close $fh; + + binmode STDOUT, ":utf8"; + print $clockid; + print "\0"; + local $, = "\0"; + print @files; +} + +sub watchman_clock { + my $response = qx/watchman clock "$git_work_tree"/; + die "Failed to get clock id on '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + + return $json_pkg->new->utf8->decode($response); +} + +sub watchman_query { + my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') + or die "open2() failed: $!\n" . + "Falling back to scanning...\n"; + + # In the query expression below we're asking for names of files that + # changed since $last_update_token but not from the .git folder. + # + # To accomplish this, we're using the "since" generator to use the + # recency index to select candidate nodes and "fields" to limit the + # output to file names only. Then we're using the "expression" term to + # further constrain the results. + my $last_update_line = ""; + if (substr($last_update_token, 0, 1) eq "c") { + $last_update_token = "\"$last_update_token\""; + $last_update_line = qq[\n"since": $last_update_token,]; + } + my $query = <<" END"; + ["query", "$git_work_tree", {$last_update_line + "fields": ["name"], + "expression": ["not", ["dirname", ".git"]] + }] + END + + # Uncomment for debugging the watchman query + # open (my $fh, ">", ".git/watchman-query.json"); + # print $fh $query; + # close $fh; + + print CHLD_IN $query; + close CHLD_IN; + my $response = do {local $/; }; + + # Uncomment for debugging the watch response + # open ($fh, ">", ".git/watchman-response.json"); + # print $fh $response; + # close $fh; + + die "Watchman: command returned no output.\n" . + "Falling back to scanning...\n" if $response eq ""; + die "Watchman: command returned invalid output: $response\n" . + "Falling back to scanning...\n" unless $response =~ /^\{/; + + return $json_pkg->new->utf8->decode($response); +} + +sub is_work_tree_watched { + my ($output) = @_; + my $error = $output->{error}; + if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) { + $retry--; + my $response = qx/watchman watch "$git_work_tree"/; + die "Failed to make watchman watch '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + $output = $json_pkg->new->utf8->decode($response); + $error = $output->{error}; + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # close $fh; + + # Watchman will always return all files on the first query so + # return the fast "everything is dirty" flag to git and do the + # Watchman query just to get it over with now so we won't pay + # the cost in git to look up each individual file. + my $o = watchman_clock(); + $error = $output->{error}; + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + output_result($o->{clock}, ("/")); + $last_update_token = $o->{clock}; + + eval { launch_watchman() }; + return 0; + } + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + return 1; +} + +sub get_working_dir { + my $working_dir; + if ($^O =~ 'msys' || $^O =~ 'cygwin') { + $working_dir = Win32::GetCwd(); + $working_dir =~ tr/\\/\//; + } else { + require Cwd; + $working_dir = Cwd::cwd(); + } + + return $working_dir; +} diff --git a/.github/git-pre-commit-hook.md b/.github/git-pre-commit-hook.md new file mode 100644 index 0000000..4c41536 --- /dev/null +++ b/.github/git-pre-commit-hook.md @@ -0,0 +1,44 @@ +# Configure local pre-commit hook + +As we aggreed to use [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) and our GitHub contract does not support pre-commit hooks, it is suggested to configure local git pre-commit scripts to check commit messages follows conventional commits. Follow next instructions to install and configure pre-commit with usefull pre-commit checks, including conventional commits check. + +## 1. Install [pre-commit](https://pre-commit.com/): + +```bash +pip install pre-commit +``` + +## 2. Add configuration to your git repo `.pre-commit-config.yaml` (usefull checks included, see included repos for more details): + +```yaml +default_install_hook_types: + - pre-commit + - commit-msg + +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v5.0.0 + hooks: + - id: trailing-whitespace + - id: check-case-conflict + - id: check-executables-have-shebangs + - id: no-commit-to-branch + - id: destroyed-symlinks + - id: mixed-line-ending + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files + + - repo: https://github.com/compilerla/conventional-pre-commit + rev: v4.2.0 + hooks: + - id: conventional-pre-commit + stages: [commit-msg] + args: [--strict, --verbose] +``` + +## 3. Install the pre-commit script: + +```bash +pre-commit install --install-hooks +``` diff --git a/.github/go-build.md b/.github/go-build.md new file mode 100644 index 0000000..078d030 --- /dev/null +++ b/.github/go-build.md @@ -0,0 +1,82 @@ +# Go Build + +## Overview + +The Go Build workflow is designed to build and test Go projects with comprehensive coverage reporting. It builds the Go project, runs tests with coverage analysis, and uploads the coverage report to SonarCloud for quality analysis. + +## Trigger + +This workflow is triggered when: +- Code is pushed to the `main` branch +- A pull request is opened, synchronized, or reopened + +## Workflow Details + +### Jobs + +#### `build` +- **Runner**: `ubuntu-latest` +- **Purpose**: Builds the Go project, runs tests, and uploads coverage reports + +### Steps + +1. **Checkout Repository** + - Uses `actions/checkout@v4` + - Fetches complete repository history (`fetch-depth: 0`) + +2. **Set up Go** + - Uses `actions/setup-go@v4` + - Configures Go version 1.23 + +3. **Build** + - Runs `go build -v ./...` + - Builds all Go packages in the repository with verbose output + +4. **Test with coverage** + - Runs `go test -v ./... -coverprofile coverage.out` + - Executes all tests with verbose output + - Generates coverage report in `coverage.out` file + +5. **Upload coverage report to SonarCloud** + - Uses `SonarSource/sonarqube-scan-action@v5` + - Uploads coverage report to SonarCloud for quality analysis + - Configures SonarCloud project settings + +## Configuration + +### Required Variables +- `SONAR_PROJECT_KEY`: SonarCloud project key +- `SONAR_ORGANIZATION`: SonarCloud organization name +- `SONAR_HOST_URL`: SonarCloud host URL + +### Required Secrets +- `SONAR_TOKEN`: SonarCloud authentication token + +### Permissions +- `contents: read` - For reading repository contents + +## Usage + +This workflow is particularly useful for: +- Building and testing Go applications +- Ensuring code quality through test coverage +- Integrating with SonarCloud for continuous quality monitoring +- Automating the build and test process for Go projects + +## Features + +- **Go 1.23 support**: Uses the latest stable Go version +- **Comprehensive testing**: Runs all tests in the repository +- **Coverage analysis**: Generates detailed coverage reports +- **SonarCloud integration**: Uploads coverage data for quality analysis +- **Verbose output**: Provides detailed build and test information + +## Categories +- Go + +## Labels +- go +- build +- test +- coverage +- sonarcloud diff --git a/.github/go-build.properties.json b/.github/go-build.properties.json new file mode 100644 index 0000000..048f81c --- /dev/null +++ b/.github/go-build.properties.json @@ -0,0 +1,7 @@ +{ + "name": "Qubership Go build", + "description": "Build a golang project and upload coverage report to SonarCloud", + "categories": [ + "Go" + ] +} diff --git a/.github/go-build.yaml b/.github/go-build.yaml new file mode 100644 index 0000000..4003f8d --- /dev/null +++ b/.github/go-build.yaml @@ -0,0 +1,43 @@ +# This workflow will build a golang project +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go + +name: Go + +on: + push: + branches: [ "main" ] + pull_request: + types: [ opened, synchronize, reopened ] + +permissions: + contents: read +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Set up Go + uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + with: + go-version: '1.23' + + - name: Build + run: go build -v ./... + + - name: Test with coverage + run: go test -v ./... -coverprofile coverage.out + + - name: Upload coverage report to SonarCloud + uses: SonarSource/sonarqube-scan-action@fd88b7d7ccbaefd23d8f36f73b59db7a3d246602 #v6.0.0 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + with: + args: > + -Dsonar.projectKey=${{ vars.SONAR_PROJECT_KEY }} + -Dsonar.organization=${{ vars.SONAR_ORGANIZATION }} + -Dsonar.host.url=${{ vars.SONAR_HOST_URL }} + -Dsonar.go.coverage.reportPaths=coverage.out diff --git a/.github/helm-charts-release-config.yaml b/.github/helm-charts-release-config.yaml new file mode 100644 index 0000000..670c190 --- /dev/null +++ b/.github/helm-charts-release-config.yaml @@ -0,0 +1,12 @@ +--- + +charts: + - name: qubership-zookeeper + chart_file: charts/helm/zookeeper-service/Chart.yaml + values_file: charts/helm/zookeeper-service/values.yaml + image: + - ghcr.io/netcracker/qubership-zookeeper-operator:${release} + - ghcr.io/netcracker/qubership-docker-zookeeper:${release}-${ZOO_VERSION} + - ghcr.io/netcracker/qubership-zookeeper-monitoring:${release} + - ghcr.io/netcracker/qubership-zookeeper-backup-daemon:${release} + - ghcr.io/netcracker/qubership-zookeeper-integration-tests:${release} diff --git a/.github/helm-charts-release.md b/.github/helm-charts-release.md new file mode 100644 index 0000000..9add872 --- /dev/null +++ b/.github/helm-charts-release.md @@ -0,0 +1,99 @@ +# Helm Charts Release + +## Overview + +The Helm Charts Release workflow is used to release Helm charts and Docker images. It includes a dry run stage to check the build process without actually publishing artifacts. The workflow is triggered manually and allows users to specify the release version. It also creates a GitHub release after successful deployment. + +## Trigger + +This workflow is triggered manually via `workflow_dispatch` with a required release version input. + +## Workflow Details + +### Jobs + +#### `check-tag` +- **Runner**: `ubuntu-latest` +- **Purpose**: Verifies if the specified release tag already exists +- **Uses**: `netcracker/qubership-workflow-hub/actions/tag-action@v1.0.4` + +#### `load-docker-build-components` +- **Runner**: `ubuntu-latest` +- **Purpose**: Loads and validates Docker build configuration +- **Outputs**: + - `component`: Docker components configuration + - `platforms`: Supported platforms configuration + +#### `docker-check-build` +- **Runner**: `ubuntu-latest` +- **Purpose**: Performs Docker build checks for each component +- **Strategy**: Matrix strategy based on components +- **Dependencies**: Requires `load-docker-build-components` and `check-tag` jobs + +### Steps + +#### check-tag Job +1. **Check if tag exists** + - Validates if the specified release tag already exists + - Prevents duplicate releases + +#### load-docker-build-components Job +1. **Checkout code** + - Uses `actions/checkout@v4` + - Checks out the repository code + +2. **Load Docker Configuration** + - Validates the Docker build configuration file + - Extracts components and platforms information + - Ensures configuration structure is valid + +#### docker-check-build Job +1. **Get version for current component** + - Sets environment variables for the current component + +2. **Docker build** + - Uses `netcracker/qubership-workflow-hub/actions/docker-action@v1.0.4` + - Performs Docker build for each component + +## Configuration + +### Required Input Parameters +- `release` (string, required): The release version to publish + +### Required Configuration +- [`.github/helm-charts-release-config.yaml`](../../config/examples/helm-charts-release-config.yaml): Configuration for the release process +- [`.github/docker-build-config.json`](../../config/examples/docker-build-config.json): Docker build configuration +- [`.github/assets-config.yml`](../../config/examples/assets-config.yml): Assets configuration +- [`.github/release-drafter-config.yml`](../../config/examples/release-drafter-config.yml): GitHub release drafter configuration +- Create a `gh-pages` branch. + +### Permissions +- `contents: write` - For creating releases and updating files +- `packages: write` - For publishing Docker images + +### Concurrency +- Prevents multiple releases from running simultaneously +- Cancels in-progress releases when a new one is started + +## Usage + +This workflow is particularly useful for: +- Releasing Helm charts with associated Docker images +- Ensuring build quality through dry-run stages +- Automating the complete release process +- Creating GitHub releases with proper assets + +## Features + +- **Dry-run support**: Test builds without publishing +- **Tag validation**: Prevents duplicate releases +- **Matrix builds**: Supports multiple Docker components +- **Configuration validation**: Ensures all required configs are valid +- **Concurrent execution control**: Prevents release conflicts +- **GitHub release integration**: Creates releases automatically + +## Categories +- Automation + +## Labels +- helm diff --git a/.github/helm-charts-release.properties.json b/.github/helm-charts-release.properties.json new file mode 100644 index 0000000..60eb591 --- /dev/null +++ b/.github/helm-charts-release.properties.json @@ -0,0 +1,11 @@ +{ + "name": "Qubership Helm charts release.", + "description": "Release and upload Helm charts to GitHub release as assets. It builds docker images and updates versions in values.yaml files.", + "categories": [ + "Automation" + ], + "filePatterns": [ + "**/Chart.yaml" + ], + "labels": [ "helm"] +} diff --git a/.github/helm-charts-release.yaml b/.github/helm-charts-release.yaml new file mode 100644 index 0000000..83c4842 --- /dev/null +++ b/.github/helm-charts-release.yaml @@ -0,0 +1,213 @@ +--- + +# This workflow is used to release Helm charts and Docker images. +# It has a dry run stage to check the build process without actually publishing the artifacts. +# The workflow is triggered manually and allows the user to specify the release version. +# The workflow also creates a GitHub release after the deployment stage if the deployment is successful. +# The workflow uses the `netcracker/qubership-workflow-hub/actions/charts-values-update-action` action to perform the release steps. +# The workflow requires the following inputs: +# - `release`: The release version to publish. +# The workflow requires several configuration files: +# - configuration file used for the release process: `.github/helm-charts-release-config.yaml` +# Example: config/examples/helm-charts-release-config.yaml +# - Docker build configuration file: `.github/docker-build-config.json` +# Example: config/examples/docker-build-config.json +# - Assets configuration file: `.github/assets-config.yml` +# Example: config/examples/assets-config.yml +# - GitHub release drafter configuration file: `.github/release-drafter-config.yml` +# Example: config/examples/release-drafter-config.yml + +name: Helm Charts Release +on: + workflow_dispatch: + inputs: + release: + description: 'Release version' + required: true + type: string + +permissions: + contents: read +run-name: ${{ github.repository }} Release ${{ github.event.inputs.release }} +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + check-tag: + runs-on: ubuntu-latest + steps: + - name: Check if tag exists + id: check_tag + uses: netcracker/qubership-workflow-hub/actions/tag-action@9319676b7d20b423a2e0943a0ac08da07d615998 #v1.0.6 + with: + tag-name: '${{ inputs.release }}' + ref: ${{ github.ref }} + create-tag: false + check-tag: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + load-docker-build-components: + runs-on: ubuntu-latest + outputs: + component: ${{ steps.load_component.outputs.components }} + platforms: ${{ steps.load_component.outputs.platforms }} + steps: + - name: Checkout code + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + + - name: Load Docker Configuration + id: load_component + run: | + verify=$(cat "$GITHUB_WORKSPACE/.github/docker-build-config.json" | jq ' + def verify_structure: + .components as $components + | .platforms as $platforms + | ($components | type == "array") + and (all($components[]; has("name") and has("file") and has("context"))) + and ($platforms | type == "string"); + verify_structure + | if . then true else false end + ') + if [ ${verify} == 'true' ]; then + echo "✅ $GITHUB_WORKSPACE/.github/docker-build-config.json file is valid" + components=$(jq -c ".components" "$GITHUB_WORKSPACE/.github/docker-build-config.json") + platforms=$(jq -c ".platforms" "$GITHUB_WORKSPACE/.github/docker-build-config.json") + else + echo "❗ $GITHUB_WORKSPACE/.github/docker-build-config.json file is invalid" + echo "❗ $GITHUB_WORKSPACE/.github/docker-build-config.json file is invalid" >> $GITHUB_STEP_SUMMARY + exit 1 + fi + echo "components=${components}" >> $GITHUB_OUTPUT + echo "platforms=${platforms}" >> $GITHUB_OUTPUT + + docker-check-build: + needs: [load-docker-build-components, check-tag] + runs-on: ubuntu-latest + strategy: + fail-fast: true + matrix: + component: ${{ fromJson(needs.load-docker-build-components.outputs.component) }} + steps: + - name: Get version for current component + id: get-version + run: | + echo "IMAGE=${{ matrix.component.name }}" >> $GITHUB_ENV + - name: Docker build + uses: netcracker/qubership-workflow-hub/actions/docker-action@9319676b7d20b423a2e0943a0ac08da07d615998 #v1.0.6 + with: + ref: ${{ github.ref }} + download-artifact: false + dry-run: true + component: ${{ toJson(matrix.component) }} + platforms: ${{ needs.load-docker-build-components.outputs.platforms }} + tags: "${{ env.IMAGE_VERSION }}" + env: + GITHUB_TOKEN: ${{ github.token }} + + chart-release-prepare: + needs: [check-tag, load-docker-build-components, docker-check-build] + permissions: + contents: write + runs-on: ubuntu-latest + outputs: + images-versions: ${{ steps.update-versions.outputs.images-versions }} + steps: + - name: Checkout code + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + fetch-depth: 0 + persist-credentials: false + - name: "Update versions in values" + id: update-versions + uses: netcracker/qubership-workflow-hub/actions/charts-values-update-action@9319676b7d20b423a2e0943a0ac08da07d615998 #v1.0.6 + with: + release-version: ${{ inputs.release }} + config-file: .github/charts-values-update-config.yaml + env: + ${{ insert }}: ${{ vars }} + - name: "Debug" + run: | + echo "Images versions: ${STEPS_UPDATE_VERSIONS_OUTPUTS_IMAGES_VERSIONS}" + env: + STEPS_UPDATE_VERSIONS_OUTPUTS_IMAGES_VERSIONS: ${{ steps.update-versions.outputs.images-versions }} + + docker-build: + needs: [chart-release-prepare, load-docker-build-components] + permissions: + contents: read + packages: write + runs-on: ubuntu-latest + strategy: + fail-fast: true + matrix: + component: ${{ fromJson(needs.load-docker-build-components.outputs.component) }} + steps: + - name: Get version for current component + id: get-version + run: | + echo "IMAGE_VERSION=${{ fromJson(needs.chart-release-prepare.outputs.images-versions)[matrix.component.name] || inputs.release }}" >> $GITHUB_ENV + + - name: Docker build + uses: netcracker/qubership-workflow-hub/actions/docker-action@9319676b7d20b423a2e0943a0ac08da07d615998 #v1.0.6 + with: + ref: release-${{ inputs.release }} + download-artifact: false + dry-run: false + component: ${{ toJson(matrix.component) }} + platforms: ${{ needs.load-docker-build-components.outputs.platforms }} + tags: "${{ env.IMAGE_VERSION }},latest" + env: + GITHUB_TOKEN: ${{ github.token }} + + charts-release: + needs: [docker-build] + continue-on-error: false + permissions: + contents: write + packages: write + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + fetch-depth: 0 + ref: release-${{ inputs.release }} + persist-credentials: false + + - name: Configure Git + run: | + git config user.name "$GITHUB_ACTOR" + git config user.email "$GITHUB_ACTOR@users.noreply.github.com" + + - name: Run chart-releaser + #continue-on-error: true + uses: netcracker/chart-releaser-action@8b8ae0a2b1c00c93200f85e3bce356b50900b590 # main + with: + charts_dir: charts/helm + release_name_template: "{{ .Version }}" + skip_existing: true + skip_upload: true + env: + CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + + - name: "Release-drafter" + uses: netcracker/release-drafter@fc6560a171e71ceb9f89462994cdcd1d4cc52005 # master + with: + config-name: release-drafter-config.yml + publish: true + name: ${{ inputs.release }} + tag: ${{ inputs.release }} + version: ${{ inputs.release }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Upload Assets + uses: netcracker/qubership-workflow-hub/actions/assets-action@9319676b7d20b423a2e0943a0ac08da07d615998 #v1.0.6 + with: + tag: ${{ inputs.release }} + item-path: .cr-release-packages/*.tgz + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/index b/.github/index new file mode 100644 index 0000000..0f6aa39 Binary files /dev/null and b/.github/index differ diff --git a/.github/license-header.md b/.github/license-header.md new file mode 100644 index 0000000..d2d7e3a --- /dev/null +++ b/.github/license-header.md @@ -0,0 +1,25 @@ +# Add/Update License Headers + +The workflow will add or update license headers in all source code files in the repository. + +## Features + +- **Customizable license headers**: The workflow supports any license header that can be specified in a text file. +- **Support for multiple file types**: The workflow can handle various file types, including Java, Go, Markdown, and more. +- **Robust file processing**: The workflow processes all files in the repository, including those in subdirectories. +- **Configurable file patterns**: You can configure the workflow to process only specific file patterns. +- **Dry run mode**: The workflow can be run in dry run mode to preview changes without modifying the repository. + +## Usage + +1. Copy the [prepared workflow file](../../workflow-templates/license-header.yml) into the `.github/workflows` directory of your repository. +2. Create a configuration file [`.licenserc.yaml`](../../config/examples/.licenserc.yaml) in the repository root with the desired license header configuration. +3. Configure the workflow by modifying the `.licenserc.yaml` file. You can specify the license type, the file patterns to process, and whether to run the workflow in dry run mode. +4. Trigger the workflow by pushing changes to the repository or by using the `workflow_dispatch` event. + +> Full documentation on `.licenserc.yaml` configuration can be found in [Apache SkyWalking Eyes documentation](https://github.com/apache/skywalking-eyes). + +## Categories + +- Automation +- Utilities diff --git a/.github/license-header.properties.json b/.github/license-header.properties.json new file mode 100644 index 0000000..c083a2f --- /dev/null +++ b/.github/license-header.properties.json @@ -0,0 +1,8 @@ +{ + "name": "Qubership License Header.", + "description": "Checks and fixes license headers in source files.", + "categories": [ + "Automation" + ], + "labels": [ "license"] +} diff --git a/.github/license-header.yml b/.github/license-header.yml new file mode 100644 index 0000000..68d5ad7 --- /dev/null +++ b/.github/license-header.yml @@ -0,0 +1,69 @@ +--- + +# The workflow needs configuration file in the root of the repository +# The default file name is `.licenserc.yaml` +# You can find configuration file example here: +# https://github.com/Netcracker/.github/blob/main/config/examples/.licenserc.yaml +# Full documentation is available here: +# https://github.com/apache/skywalking-eyes + +name: Add License Headers +on: + push: + branches: + - main + workflow_dispatch: + inputs: + commit-message: + description: 'Commit message for the license header changes' # Applicable for mode 'fix' + type: string + required: false + default: 'chore: add license headers to source files' # Applicable for mode 'fix' + title: + type: string + description: 'Title for the pull request' + required: false + default: 'chore: add license headers to source files' # Applicable for mode 'fix' + body: + type: string + description: 'Body for the pull request' + required: false + default: 'This PR adds Apache license headers to all applicable source files.' # Applicable for mode 'fix' + mode: + type: choice + description: 'Mode for the license header action' + required: false + default: 'fix' + options: + - fix + - check +permissions: + contents: read + +jobs: + license: + permissions: + contents: write + pull-requests: write + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + + - name: Fix License Header + continue-on-error: true + uses: apache/skywalking-eyes/header@v0.7.0 + with: + mode: ${{ inputs.mode || 'fix' }} # default to fix + + - name: Create Pull Request + if: inputs.mode == 'fix' || github.event_name == 'push' + uses: peter-evans/create-pull-request@v7.0.8 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: "${{ inputs.commit-message || 'chore: add license headers to source files' }}" + title: "${{ inputs.title || 'chore: add license headers to source files' }}" + body: "${{ inputs.body || 'This PR adds Apache license headers to all applicable source files.'}}" + branch: add-license-headers + base: main diff --git a/.github/link-checker.md b/.github/link-checker.md new file mode 100644 index 0000000..cd6cfd2 --- /dev/null +++ b/.github/link-checker.md @@ -0,0 +1,67 @@ +# Link Checker + +## Overview + +The Link Checker workflow validates all links in Markdown files within the repository. It uses the Lychee link checker to identify broken, inaccessible, or problematic links, helping maintain the quality and reliability of documentation. + +## Trigger + +This workflow is triggered when: +- Code is pushed to any branch +- Repository dispatch events occur +- Manually via `workflow_dispatch` + +## Workflow Details + +### Jobs + +#### `linkChecker` +- **Runner**: `ubuntu-latest` +- **Purpose**: Checks all Markdown files for broken or problematic links + +### Steps + +1. **Checkout Repository** + - Uses `actions/checkout@v4` + - Checks out the repository code + +2. **Link Checker** + - Uses `lycheeverse/lychee-action@v2` + - Scans all Markdown files (`./**/*.md`) for links + - Provides detailed link validation with configurable settings + +## Configuration + +### Link Checker Settings +- **Target files**: `./**/*.md` (all Markdown files recursively) +- **Verbose output**: Enabled for detailed reporting +- **Progress display**: Disabled for cleaner output +- **User agent**: Chrome browser user agent for compatibility +- **Retry settings**: 5 retries with 30-second wait time +- **Acceptable status codes**: 100-103, 200-299, 429 (rate limited) +- **Cookie jar**: Uses `cookies.json` for session management +- **Private links**: Excludes all private/internal links +- **Output format**: Markdown format +- **Failure mode**: Fails the workflow on broken links + +## Usage + +This workflow is particularly useful for: +- Maintaining documentation quality +- Identifying broken external links +- Ensuring documentation accessibility +- Preventing link rot in repositories +- Validating documentation before releases + +## Features + +- **Comprehensive scanning**: Checks all Markdown files recursively +- **Robust retry logic**: Handles temporary network issues +- **Rate limit handling**: Accepts 429 status codes +- **Session management**: Uses cookies for authenticated links +- **Detailed reporting**: Provides verbose output for troubleshooting +- **Fail-fast behavior**: Stops on first broken link + +## Categories +- Automation +- Utilities diff --git a/.github/link-checker.properties.json b/.github/link-checker.properties.json new file mode 100644 index 0000000..413dcd7 --- /dev/null +++ b/.github/link-checker.properties.json @@ -0,0 +1,10 @@ +{ + "name": "Qubership Markdown link checker", + "description": "Check Markdown files for broken links", + + "categories": [ + "Automation", + "utilities" + ], + "labels": [ "preview"] +} diff --git a/.github/link-checker.yaml b/.github/link-checker.yaml new file mode 100644 index 0000000..8d204b6 --- /dev/null +++ b/.github/link-checker.yaml @@ -0,0 +1,47 @@ +--- +name: Link Checker + +on: + push: null + repository_dispatch: null + workflow_dispatch: null + pull_request: + branches: [main] +permissions: + contents: read +jobs: + linkChecker: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + + - name: Restore lychee cache + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + id: restore-cache + with: + path: .lycheecache + key: cache-lychee-${{ github.sha }} + restore-keys: cache-lychee- + + - name: Link Checker + id: lychee + uses: lycheeverse/lychee-action@885c65f3dc543b57c898c8099f4e08c8afd178a2 #v2.6.1 + with: + args: >- + './**/*.md' + --verbose + --no-progress + --user-agent 'Mozilla/5.0 (X11; Linux x86_64) Chrome/134.0.0.0' + --retry-wait-time 60 + --max-retries 8 + --accept 100..=103,200..=299,429 + --cookie-jar cookies.json + --exclude-all-private + --max-concurrency 4 + --cache + --cache-exclude-status '429, 500..502' + --max-cache-age 1d + format: markdown + fail: true diff --git a/.github/lint-test-chart.md b/.github/lint-test-chart.md new file mode 100644 index 0000000..49d7fa7 --- /dev/null +++ b/.github/lint-test-chart.md @@ -0,0 +1,93 @@ +# Lint and Test Charts + +## Overview + +The Lint and Test Charts workflow validates Helm charts through linting and testing processes. It uses chart-testing tools to ensure Helm charts are properly formatted, follow best practices, and can be successfully installed in a Kubernetes cluster. + +## Trigger + +This workflow is triggered when: +- A pull request is created or updated +- Manually via `workflow_dispatch` with optional input parameters + +## Workflow Details + +### Jobs + +#### `lint-test` +- **Runner**: `ubuntu-latest` +- **Purpose**: Lints and tests Helm charts using chart-testing tools + +### Steps + +1. **Checkout** + - Uses `actions/checkout@v3` + - Fetches complete repository history (`fetch-depth: 0`) + +2. **Set up Helm** + - Uses `azure/setup-helm@v4.2.0` + - Installs Helm version 3.17.0 + +3. **Set up Python** + - Uses `actions/setup-python@v5.3.0` + - Installs Python 3.x with latest available version + +4. **Set up chart-testing** + - Uses `helm/chart-testing-action@v2.7.0` + - Installs chart-testing tools + +5. **Run chart-testing (list-changed)** + - Identifies which charts have changed compared to the target branch + - Sets output variable to determine if linting/testing should proceed + +6. **Run chart-testing (lint)** + - Runs linting on changed charts + - Condition: Only runs if charts have changed or manual trigger is used + +7. **Create kind cluster** + - Uses `helm/kind-action@v1.12.0` + - Creates a local Kubernetes cluster for testing + - Condition: Only runs if charts have changed or manual trigger is used + +8. **Run chart-testing (install)** + - Installs and tests charts in the kind cluster + - Condition: Only runs if charts have changed or manual trigger is used + +## Configuration + +### Input Parameters (Manual Trigger) +- `lint-n-test` (boolean, optional): Force run lint and test charts (default: false) + +### Required Tools +- **Helm**: Version 3.17.0 +- **Python**: 3.x +- **chart-testing**: Latest version from chart-testing-action +- **kind**: Kubernetes cluster for testing + +## Usage + +This workflow is particularly useful for: +- Validating Helm chart syntax and structure +- Ensuring charts follow Helm best practices +- Testing chart installation in a real Kubernetes environment +- Catching issues before charts are deployed to production +- Maintaining chart quality standards + +## Features + +- **Smart execution**: Only processes changed charts on pull requests +- **Comprehensive testing**: Lints charts and tests installation +- **Real cluster testing**: Uses kind cluster for realistic testing +- **Manual override**: Can force execution via manual trigger +- **Latest tooling**: Uses current versions of Helm and chart-testing + +## Categories +- Helm +- Testing +- CI/CD + +## Labels +- helm +- charts +- testing +- linting diff --git a/.github/lint-test-chart.yaml b/.github/lint-test-chart.yaml new file mode 100644 index 0000000..6534f0b --- /dev/null +++ b/.github/lint-test-chart.yaml @@ -0,0 +1,57 @@ +name: Lint and Test Charts + +on: + pull_request: + workflow_dispatch: + inputs: + lint-n-test: + type: boolean + default: false + required: false + description: Run lint and test charts + +permissions: + contents: read + +jobs: + lint-test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + fetch-depth: 0 + + - name: Set up Helm + uses: azure/setup-helm@v4.3.1 + with: + version: v3.17.0 + + - uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 + with: + python-version: '3.x' + check-latest: true + + - name: Set up chart-testing + uses: helm/chart-testing-action@v2.7.0 + + - name: Run chart-testing (list-changed) + id: list-changed + run: | + changed=$(ct list-changed --target-branch ${{ github.event.repository.default_branch }}) + if [[ -n "$changed" ]]; then + echo "changed=true" >> "$GITHUB_OUTPUT" + fi + + - name: Run chart-testing (lint) + if: steps.list-changed.outputs.changed == 'true' || inputs.lint-n-test == true + run: ct lint --target-branch ${{ github.event.repository.default_branch }} + + - name: Create kind cluster + if: steps.list-changed.outputs.changed == 'true' || inputs.lint-n-test == true + uses: helm/kind-action@v1.12.0 + + - name: Run chart-testing (install) + if: steps.list-changed.outputs.changed == 'true' || inputs.lint-n-test == true + run: ct install --target-branch ${{ github.event.repository.default_branch }} diff --git a/.github/main b/.github/main new file mode 100644 index 0000000..81f8ecd --- /dev/null +++ b/.github/main @@ -0,0 +1 @@ +01154b818dc4b2b96acd3e6804572db5d748564d diff --git a/.github/maven-publish-pom-preparation_doc.md b/.github/maven-publish-pom-preparation_doc.md new file mode 100644 index 0000000..e10e50a --- /dev/null +++ b/.github/maven-publish-pom-preparation_doc.md @@ -0,0 +1,199 @@ +# Prepare your project to publish into Maven Central + +This documentation provides the instruction how to change project's `pom.xml` file to be able to publish artifacts into Maven Central. + +--- + +## POM file required changes + +### Mandatory maven central properties + +Add following entries under `project` section (see [maven central requirements](https://central.sonatype.org/publish/requirements/) for more info). Make sure to update description, `url` and `scm` sections according to your project details. + +```xml + ${project.groupId}:${project.artifactId} + Your project description + https://github.com/Netcracker/your-repository + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0 + + + + + Netcracker + opensourcegroup@netcracker.com + Netcracker Technology + https://www.netcracker.com + + + + scm:git:https//github.com/Netcracker/your-repository.git + scm:git:https://github.com/Netcracker/your-repository.git + scm:git:https://github.com/Netcracker/your-repository.git + +``` + +### Distribution management + +To have a possibility to deploy release and SNAPSHOT versions to Maven Central and GitHub packages add `profiles` under `project` section + +```xml + + + + + central + + true + + + + + org.sonatype.central + central-publishing-maven-plugin + 0.7.0 + true + + central + true + published + + + + + + + central + Central Maven Repository + + true + + + + + + + + github + + false + + + + github + GitHub Packages + https://maven.pkg.github.com/Netcracker/REPOSITORY_NAME + + + + +``` + +### Snapshots repository + +Under `project/repositories` add new repositories + +```xml + + + + oss.sonatype.org + https://central.sonatype.com + + true + + + false + + + + + + oss.sonatype.org-snapshot + https://central.sonatype.com/repository/maven-snapshots + + false + + + true + + + + + + github + https://maven.pkg.github.com/netcracker/* + + true + + + true + + + +``` + +### Build plugins + +In a section `project.build.plugins` add next entries: + +```xml + + + + org.apache.maven.plugins + maven-gpg-plugin + 3.2.7 + + + sign-artifacts + verify + + sign + + + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.3.0 + + + attach-sources + + jar-no-fork + + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.6.3 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-release-plugin + 3.1.1 + + + org.codehaus.mojo + versions-maven-plugin + 2.18.0 + +``` diff --git a/.github/maven-publish-secrets_doc.md b/.github/maven-publish-secrets_doc.md new file mode 100644 index 0000000..d774113 --- /dev/null +++ b/.github/maven-publish-secrets_doc.md @@ -0,0 +1,165 @@ +## Preparing GPG Key to Sign Java Artifacts + +To publish Java artifacts to Maven Central, you need to sign them with a GPG key. Follow these steps to prepare your GPG key: + +### Step 1: Install GPG + +Ensure you have GPG installed on your system. You can download and install it from [GnuPG's official website](https://gnupg.org/download/). + +### Step 2: Generate a New GPG Key + +Open your terminal and run the following command to generate a new GPG key: + +```sh +gpg --full-generate-key +``` + +Follow the prompts to configure your key. Choose the following options: + +- Key type: RSA and RSA +- Key size: 4096 bits +- Expiration: Choose an appropriate expiration date +- Real name: Your name +- Email address: Your email address +- Comment: Optional + +### Step 3: List Your GPG Keys + +To list your GPG keys and find the key ID, run: + +```sh +gpg --list-keys +``` + +Note the key ID (a 16-character hexadecimal string). + +### Step 4: Publish Your GPG Key + +To publish your GPG key to a key server, run: + +```sh +gpg --keyserver keyserver.ubuntu.com --send-keys +``` + +Replace `` with your actual key ID. + +### Step 5: Verify Your Key on the Keyserver + +To verify that your key has been uploaded successfully, you can search for it on the keyserver: + +```bash +gpg --keyserver keyserver.ubuntu.com --search-keys +``` + +### Step 6: Configure Maven to Use Your GPG Key + +Add the following configuration to your `pom.xml` file to sign your artifacts: + +```xml + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + sign-artifacts + verify + + sign + + + + + + --pinentry-mode + loopback + + + + + +``` + +### Step 7: Provide GPG Passphrase + +When running Maven commands, you will be prompted to enter your GPG passphrase. You can also configure Maven to use the passphrase automatically by adding it to your `settings.xml` file (not recommended for security reasons). In case of using GitHub workflow the `settings.xml` will be created automatically and store the secrets secure way. + +With these steps, your Java artifacts will be signed with your GPG key. + +## Configure a GitHub repository to publish artifacts to Maven Central + +To configure a GitHub repository to publish artifacts to Maven Central, you need to set up GitHub Actions workflows and add specific secrets to your repository. Here are the steps: + +### Step 1: Set Up GitHub Actions Workflow + +Create a GitHub Actions workflow file in your repository. For example, create a file named .github/workflows/release.yml with the following content: + +```yaml +--- +name: Release + +on: + workflow_dispatch: + inputs: + revision: + required: false + type: string + release_info: + required: false + type: string + java_version: + required: false + type: string + default: "21" + +jobs: + pom: + uses: Netcracker/qubership-workflow-hub/.github/workflows/update-pom-release.yml@v1.0.7 + with: + file: pom.xml + revision: ${{ github.event.inputs.revision }} + + git_release: + uses: Netcracker/qubership-workflow-hub/.github/workflows/create-github-release.yml@v1.0.7 + needs: pom + with: + revision: ${{ github.event.inputs.revision }} + release_info: ${{ github.event.inputs.release_info }} + draft: false + prerelease: false + + maven: + uses: Netcracker/qubership-workflow-hub/.github/workflows/maven-publish.yml@v1.0.7 + needs: git_release + with: + maven_command: "--batch-mode deploy" + java_version: "21" + revision: ${{ github.event.inputs.revision }} + secrets: + maven_username: ${{ secrets.MAVEN_USER }} + maven_password: ${{ secrets.MAVEN_PASSWORD }} + maven_gpg_passphrase: ${{ secrets.MAVEN_GPG_PASSPHRASE }} + maven_gpg_private_key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} +``` + +### Step 2: Add Secrets to Your GitHub Repository + +Go to your repository settings and add the following secrets: + +`MAVEN_GPG_PRIVATE_KEY`: Your GPG private key, exported as an ASCII-armored string. +`MAVEN_GPG_PASSPHRASE`: The passphrase for your GPG key. +`MAVEN_USER`: Your Maven Central username. +`MAVEN_PASSWORD`: Your Maven Central token. + +Exporting GPG Private Key +To export your GPG private key, run the following command and copy the output: + +```bash +gpg --armor --export-secret-keys +``` + +Add the exported key as the value of the `MAVEN_GPG_PRIVATE_KEY` secret. + +With these steps, your GitHub Actions workflow will build your project and deploy the artifacts to Maven Central. diff --git a/.github/maven-release-v2.md b/.github/maven-release-v2.md new file mode 100644 index 0000000..1ad4fd7 --- /dev/null +++ b/.github/maven-release-v2.md @@ -0,0 +1,36 @@ +# Maven project release workflow + +Maven project release workflow is used to make a GitHub release and publish released artifacts into Maven Central or GitHub packages. +The workflow consists of several sequential jobs: + +1. Checks if the tag already exists. +2. Builds current snapshot versions (dry run step) +3. Prepares release using Maven (maven-release-plugin) +4. Builds and deploys the project using Maven (maven-release-plugin). +5. Builds and publishes a Docker image if there is Dockerfile. +6. Create GitHub release + +To make it use one need to do several preparations in the project. + +## Step 1: Prepare pom.xml + +First of all please make sure the `pom.xml` file prepared to build source code and java doc jars alongside with main artifact. You need to sign all publishing artifacts with PGP key too. The instruction on how to do it can be found here [Prepare your project to publish into Maven Central](https://github.com/Netcracker/.github/blob/main/docs/maven-publish-pom-preparation_doc.md) + +## Step 2: Maven release workflow + +Copy the [prepared file](https://github.com/Netcracker/.github/blob/main/workflow-templates/maven-release-v2.yaml) into `.github/workflows` directory of your repository. + +This workflow is designed to be run manually. It has four input parameters on manual execution: + +- `Version type to release` -- a string represents version type to release: `patch`, `minor` or `major` +- `Maven profile to use` -- maven profile can be `central` or `github`. +- `Additional maven arguments to pass` -- additional arguments to pass to `mvn` command. +- `Build Docker image` -- build and publish docker image to GitHub packages if Dockerfile exists + +## Step 3: Add configuration file for GitHub release + +Upload [prepared configuration file](https://github.com/Netcracker/.github/blob/main/config/examples/release-drafter-config.yml) to your repository in `.github` folder. You can customize it in future for your needs. + +## Step 4: Prepare actions secrets + +The workflow needs several secrets to be prepared to work properly. For `Netcracker` repositories all of them already prepared, configured and available for use. You can find them in table [The organization level secrets and vars used in actions](#the-organization-level-secrets-and-vars-used-in-actions). Detailed instructions on how to generate a GPG key and set up secrets in a GitHub repository can be found in [this document](https://github.com/Netcracker/.github/blob/main/docs/maven-publish-secrets_doc.md). diff --git a/.github/maven-release-v2.properties.json b/.github/maven-release-v2.properties.json new file mode 100644 index 0000000..d03759b --- /dev/null +++ b/.github/maven-release-v2.properties.json @@ -0,0 +1,12 @@ +{ + "name": "Qubership Release And Upload to Maven Central or GitHub Packages", + "description": "Release And Upload to Maven Central or GitHub packages workflow template. It uses power of maven-release-plugin.", + "categories": [ + "Java", + "Automation", + "Maven" + ], + "filePatterns": [ + "^pom.xml" + ] +} diff --git a/.github/maven-release-v2.yaml b/.github/maven-release-v2.yaml new file mode 100644 index 0000000..35ddecc --- /dev/null +++ b/.github/maven-release-v2.yaml @@ -0,0 +1,172 @@ +--- +# This workflow is used to build and publish a Maven project to a Maven repository (GitHub packages or Maven Central). +# It has a dry run stage to check the build process without actually publishing the artifacts. +# The workflow is triggered manually and allows the user to specify the version type (major, minor, patch), Maven profile, and additional Maven arguments. +# The workflow also creates a GitHub release after the deployment stage if the deployment is successful. +# The workflow uses the `netcracker/qubership-workflow-hub/actions/maven-release` action to perform the build and publish steps. +# The workflow requires the following inputs: +# - `version-type`: The type of version to release (major, minor, patch). +# - `maven-args`: Additional Maven arguments to pass (e.g. -DskipTests=true -Dmaven.javadoc.skip=true). +# - `profile`: The Maven profile to use (e.g. github, central). +# Please make sure to set the required secrets in your GitHub repository: +# - `GITHUB_TOKEN`: The GitHub token used for authentication. +# - `GPG_PRIVATE_KEY`: The GPG private key used for signing the artifacts. +# - `GPG_PASSPHRASE`: The passphrase for the GPG private key. +# - `MAVEN_USER`: The Maven username used for authentication (for Maven Central). +# - `MAVEN_PASSWORD`: The Maven password used for authentication (for Maven Central). +# - `GH_BUMP_VERSION_APP_ID`: The GitHub App ID used for authentication. +# - `GH_BUMP_VERSION_APP_KEY`: The private key for the GitHub App used for authentication. +# The workflow also requires the https://github.com/Netcracker/.github/blob/main/config/examples/release-drafter-config.yml config file to create a GitHub release. +# Please prepare project's pom.xml file according to https://github.com/netcracker/.github/blob/main/docs/maven-publish-pom-preparation_doc.md +# to be able to use this workflow. + +name: Maven release + +run-name: ${{ github.event.inputs.version-type }} release for ${{ github.event.repository.name }} + +on: + workflow_dispatch: + inputs: + version-type: + description: "Version type to release" + type: choice + options: + - "major" + - "minor" + - "patch" + required: true + default: "patch" + profile: + description: "Maven profile to use" + type: choice + options: + - "github" + - "central" + required: false + default: "central" + mvn-args: + description: "Additional maven arguments to pass (e.g. -DskipTests=true -Dmaven.javadoc.skip=true)" + required: false + default: "" + type: string + build-docker: + description: "Build Docker image" + required: false + default: false + type: boolean + +permissions: + contents: read + +jobs: + dry-run-build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: "Build and Publish current SNAPSHOT (dry run)" + uses: netcracker/qubership-workflow-hub/actions/maven-release@9319676b7d20b423a2e0943a0ac08da07d615998 #v1.0.6 + with: + version-type: ${{ github.event.inputs.version-type }} + ref: ${{ github.ref }} + module: ${{ github.event.repository.name }} + maven-args: ${{ inputs.mvn-args }} + profile: ${{ inputs.profile }} + server-id: ${{ inputs.profile }} + token: ${{ secrets.GITHUB_TOKEN }} + maven-user: ${{ inputs.profile == 'github' && github.actor || secrets.MAVEN_USER }} + maven-password: ${{ inputs.profile == 'github' && secrets.GITHUB_TOKEN || secrets.MAVEN_PASSWORD }} + gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} + gpg-passphrase: ${{ secrets.MAVEN_GPG_PASSPHRASE }} + dry-run: "true" + deploy: + needs: [dry-run-build] + if: ${{ needs.dry-run-build.result == 'success' }} + runs-on: ubuntu-latest + permissions: + contents: write + packages: write + outputs: + release-version: ${{ steps.build-and-publish.outputs.release-version }} + steps: + # This step is needed if there is a GitHub App used for authentication to bypass the protected branch rule + - name: "Prepare app token" + uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4 + id: app-token + with: + app-id: ${{ vars.GH_BUMP_VERSION_APP_ID }} + private-key: ${{ secrets.GH_BUMP_VERSION_APP_KEY }} + + - name: "Build and Publish" + id: build-and-publish + uses: netcracker/qubership-workflow-hub/actions/maven-release@9319676b7d20b423a2e0943a0ac08da07d615998 #v1.0.6 + with: + version-type: ${{ github.event.inputs.version-type }} + ref: ${{ github.ref }} + module: ${{ github.event.repository.name }} + maven-args: ${{ inputs.mvn-args }} + profile: ${{ inputs.profile }} + server-id: ${{ inputs.profile }} + token: ${{ steps.app-token.outputs.token }} # It can be ${{ secrets.GITHUB_TOKEN }} if default branch isn't protected + maven-user: ${{ inputs.profile == 'github' && github.actor || secrets.MAVEN_USER }} + maven-password: ${{ inputs.profile == 'github' && secrets.GITHUB_TOKEN || secrets.MAVEN_PASSWORD }} + gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} + gpg-passphrase: ${{ secrets.MAVEN_GPG_PASSPHRASE }} + dry-run: "false" + + - name: Upload all Maven target directories + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: ${{ github.event.repository.name }} + path: "${{ github.event.repository.name }}/**/target" # Upload all target directories in the repository + check-dockerfile: + needs: [deploy] + if: ${{ github.event.inputs.build-docker == 'true' }} + runs-on: ubuntu-latest + permissions: + contents: read + outputs: + dockerfile_exists: ${{ steps.check_dockerfile.outputs.df_exists }} + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: "Check Dockerfile existence" + id: check_dockerfile + shell: bash + run: | + if [[ -f Dockerfile ]]; then + echo "df_exists=exists" >> "$GITHUB_OUTPUT" + else + echo "Dockerfile does not exist. Docker build stage will be skipped" + echo "df_exists=notexists" >> "$GITHUB_OUTPUT" + fi + echo "GITHUB_OUTPUT:" + cat "$GITHUB_OUTPUT" + + docker-build: + if: ${{ github.event.inputs.build-docker == 'true' && needs.check-dockerfile.outputs.dockerfile_exists == 'exists' }} + permissions: + contents: read + packages: write + runs-on: ubuntu-latest + needs: [check-dockerfile, deploy] + steps: + - name: "Docker Build" + id: docker_build + uses: netcracker/qubership-workflow-hub/actions/docker-action@9319676b7d20b423a2e0943a0ac08da07d615998 #v1.0.6 + with: + ref: v${{ needs.deploy.outputs.release-version }} + download-artifact: true + env: + GITHUB_TOKEN: ${{ github.token }} + + github-release: + needs: [deploy] + permissions: + contents: write + if: ${{ needs.deploy.result == 'success' }} + uses: netcracker/qubership-workflow-hub/.github/workflows/release-drafter.yml@9319676b7d20b423a2e0943a0ac08da07d615998 #v1.0.6 + with: + version: ${{ needs.deploy.outputs.release-version }} + publish: true diff --git a/.github/maven-release.md b/.github/maven-release.md new file mode 100644 index 0000000..063fbea --- /dev/null +++ b/.github/maven-release.md @@ -0,0 +1,96 @@ +# Maven Release + +## Overview + +The Maven Release workflow is designed to be triggered when a release is marked as a full release. It performs a comprehensive release process including version management, building, testing, tagging, and deployment to Maven repositories. + +## Trigger + +This workflow is triggered manually via `workflow_dispatch` with configurable input parameters. + +## Workflow Details + +### Jobs + +#### `check-tag` +- **Runner**: `ubuntu-latest` +- **Purpose**: Validates input parameters and checks if the release tag already exists +- **Uses**: `netcracker/qubership-workflow-hub/actions/tag-checker@v1.0.4` + +#### `update-pom-version` +- **Runner**: `ubuntu-latest` +- **Purpose**: Updates the version in pom.xml and commits changes +- **Dependencies**: Requires `check-tag` job completion +- **Outputs**: `artifact_id` from configuration + +### Steps + +#### check-tag Job +1. **Input parameters** + - Displays version and Java version in workflow summary + +2. **Checkout code** + - Uses `actions/checkout@v4` + - Checks out the repository code + +3. **Check if tag exists** + - Validates if the release tag already exists + - Prevents duplicate releases + +4. **Output result** + - Logs tag existence status and tag name + +5. **Fail if tag exists** + - Terminates workflow if tag already exists + +#### update-pom-version Job +1. **Checkout code** + - Uses `actions/checkout@v4` + - Fetches complete repository history + +2. **Update pom.xml** + - Updates version information in pom.xml file + +## Configuration + +### Required Input Parameters +- `version` (string, required): Release version (e.g., 1.0.0) + +### Optional Input Parameters +- `java-version` (string, optional): Java version to use (default: "21") +- `build-docker` (boolean, optional): Release docker image if Dockerfile exists (default: true) +- `profile` (choice, required): Release mode - 'github' or 'central' (default: 'central') +- `dry-run` (boolean, optional): Enable dry-run mode (default: false) + +### Permissions +- `contents: write` - For updating pom.xml and creating releases +- `packages: write` - For publishing Maven artifacts + +## Usage + +This workflow is particularly useful for: +- Automating Maven project releases +- Publishing artifacts to Maven Central or GitHub Packages +- Creating GitHub releases with proper versioning +- Building and publishing Docker images alongside Maven artifacts +- Ensuring release quality through comprehensive testing + +## Features + +- **Version management**: Automatically updates pom.xml with release version +- **Tag validation**: Prevents duplicate releases +- **Multiple deployment targets**: Supports Maven Central and GitHub Packages +- **Docker integration**: Optionally builds and publishes Docker images +- **Dry-run support**: Test releases without actual deployment +- **Comprehensive testing**: Runs tests before deployment + +## Categories +- Java +- Automation +- Maven + +## Labels +- maven +- release +- java +- central diff --git a/.github/maven-release.properties.json b/.github/maven-release.properties.json new file mode 100644 index 0000000..d10bca4 --- /dev/null +++ b/.github/maven-release.properties.json @@ -0,0 +1,12 @@ +{ + "name": "Qubership Release And Upload to Maven Central", + "description": "Release And Upload to Maven Central workflow template. It can be used to create GitHub release and upload artifacts to Maven Central.", + "categories": [ + "Java", + "Automation", + "Maven" + ], + "filePatterns": [ + "^pom.xml" + ] +} diff --git a/.github/maven-release.yaml b/.github/maven-release.yaml new file mode 100644 index 0000000..3ca7b6b --- /dev/null +++ b/.github/maven-release.yaml @@ -0,0 +1,210 @@ +--- + +# This GitHub Actions workflow is designed to be triggered when a release is marked as a full release. +# The workflow performs the following tasks: +# 1. Checks if the tag already exists. +# 2. Updates the version in the pom.xml file. +# 3. Commits the changes to the repository. +# 4. Builds the project using Maven. +# 5. Runs tests. +# 6. Tags the commit with the release version. +# 7. Deploys the artifact to the Maven repository. +# 8. Builds and publishes a Docker image. +# 9. Creates a GitHub release. + +# To make it work for your project, you need to adjust the pom.xml and add configuration file for GitHub release. +# Please find detailed instructions: +# https://github.com/netcracker/qubership-workflow-hub?tab=readme-ov-file#maven-project-release-workflow + +name: Release And Deploy Maven Artifact + +on: + workflow_dispatch: + inputs: + version: + required: true + default: '1.0.0' + type: string + description: 'Release version (e.g., 1.0.0)' + java-version: + required: false + type: string + default: "21" + description: 'Java version (e.g., 21)' + build-docker: + required: false + type: boolean + default: true + description: 'Release docker image if there is Docker file' + profile: + type: choice + default: 'central' + description: 'Release mode (github or central)' + required: true + options: + - github + - central + dry-run: + required: false + type: boolean + default: false + description: 'Dry run' + +permissions: + contents: read + +jobs: + check-tag: + runs-on: ubuntu-latest + steps: + - name: Input parameters + run: | + echo "Version: ${{ github.event.inputs.version }}" >> $GITHUB_STEP_SUMMARY + echo "Java version: ${{ github.event.inputs.java-version }}" >> $GITHUB_STEP_SUMMARY + + - name: Checkout code + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + + - name: Check if tag exists + id: check_tag + uses: netcracker/qubership-workflow-hub/actions/tag-checker@v2.0.0 + with: + tag: 'v${{ github.event.inputs.version }}' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Output result + run: | + echo "Tag exists: ${{ steps.check_tag.outputs.exists }}" + echo "Tag name: v${{ github.event.inputs.version }}" + + - name: Fail if tag exists + if: steps.check_tag.outputs.exists == 'true' + run: | + echo "Tag already exists: v${{ github.event.inputs.version }}" >> $GITHUB_STEP_SUMMARY + echo "Tag already exists: v${{ github.event.inputs.version }}" + exit 1 + + update-pom-version: + permissions: + contents: write + needs: [check-tag] + runs-on: ubuntu-latest + outputs: + artifact_id: ${{ steps.config.outputs.artifact_id }} + steps: + - name: Checkout code + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Update pom.xml + id: config + uses: netcracker/qubership-workflow-hub/actions/pom-updater@9319676b7d20b423a2e0943a0ac08da07d615998 #v1.0.6 + with: + new_value: ${{ github.event.inputs.version }} + + - name: Commit Changes + uses: netcracker/qubership-workflow-hub/actions/commit-and-push@9319676b7d20b423a2e0943a0ac08da07d615998 #v1.0.6 + with: + commit_message: "Update pom.xml version to ${{ github.event.inputs.version }}" + + mvn-package: + needs: [update-pom-version] + uses: netcracker/qubership-workflow-hub/.github/workflows/maven-publish.yml@9319676b7d20b423a2e0943a0ac08da07d615998 #v1.0.6 + with: + maven-command: "--batch-mode package" + java-version: ${{ github.event.inputs.java-version }} + upload-artifact: true + artifact-id: ${{ needs.update-pom-version.outputs.artifact_id }} + ref: ${{ github.ref }} + secrets: + maven-username: ${{ secrets.MAVEN_USER }} + maven-token: ${{ secrets.MAVEN_PASSWORD }} + gpg-passphrase: ${{ secrets.MAVEN_GPG_PASSPHRASE }} + gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} + + tests: + needs: [mvn-package] + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + + - name: Run tests + run: echo "Running tests here" + + tag: + permissions: + contents: write + needs: [tests] + uses: netcracker/qubership-workflow-hub/.github/workflows/tag-creator.yml@9319676b7d20b423a2e0943a0ac08da07d615998 #v1.0.6 + with: + tag-name: "v${{ github.event.inputs.version }}" + + mvn-deploy: + needs: [update-pom-version, tag] + permissions: + contents: write + packages: write + uses: netcracker/qubership-workflow-hub/.github/workflows/maven-publish.yml@9319676b7d20b423a2e0943a0ac08da07d615998 #v1.0.6 + with: + maven-command: ${{ (github.event.inputs.dry-run == 'true' && '--batch-mode package') || github.event.inputs.profile == 'github' && '--batch-mode deploy -P github' || '--batch-mode deploy -P central' }} + java-version: ${{ github.event.inputs.java-version }} + upload-artifact: false + artifact-id: ${{ needs.update-pom-version.outputs.artifact_id }} + server-id: ${{ inputs.profile }} + ref: ${{ github.ref }} + secrets: + maven-username: ${{ secrets.MAVEN_USER }} + maven-token: ${{ secrets.MAVEN_PASSWORD }} + gpg-passphrase: ${{ secrets.MAVEN_GPG_PASSPHRASE }} + gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} + + check-dockerfile: + runs-on: ubuntu-latest + needs: [update-pom-version, tag] + outputs: + dockerfile_exists: ${{ steps.check_dockerfile.outputs.df_exists }} + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + - name: "Check Dockerfile existence" + id: check_dockerfile + shell: bash + run: | + if [[ -f Dockerfile ]]; then + echo "df_exists=exists" >> "$GITHUB_OUTPUT" + else + echo "Dockerfile does not exist. Docker build stage will be skipped" + echo "df_exists=notexists" >> "$GITHUB_OUTPUT" + fi + echo "GITHUB_OUTPUT:" + cat "$GITHUB_OUTPUT" + + docker-build-publish: + permissions: + contents: read + packages: write + needs: [update-pom-version, tag, check-dockerfile] + if: ${{ github.event.inputs.build-docker == 'true' && needs.check-dockerfile.outputs.dockerfile_exists == 'exists' }} + uses: netcracker/qubership-workflow-hub/.github/workflows/docker-publish.yml@9319676b7d20b423a2e0943a0ac08da07d615998 #v1.0.6 + with: + ref: "v${{ github.event.inputs.version }}" + artifact-id: ${{ needs.update-pom-version.outputs.artifact_id }} + dry-run: ${{ inputs.dry-run }} + + github-release: + permissions: + contents: write + needs: [tag] + uses: netcracker/qubership-workflow-hub/.github/workflows/release-drafter.yml@9319676b7d20b423a2e0943a0ac08da07d615998 #v1.0.6 + with: + version: ${{ github.event.inputs.version }} + publish: false diff --git a/.github/maven-snapshot-deploy.md b/.github/maven-snapshot-deploy.md new file mode 100644 index 0000000..cf98101 --- /dev/null +++ b/.github/maven-snapshot-deploy.md @@ -0,0 +1,83 @@ +# Maven Snapshot Deploy + +## Overview + +The Maven Snapshot Deploy workflow is used to deploy Maven snapshot artifacts to GitHub packages or Maven Central repository. It is triggered on pushes to branches other than main and release branches, providing continuous deployment of development builds. + +## Trigger + +This workflow is triggered when: +- Code is pushed to any branch except: + - `main` + - `**release*` (any release branch) + - `prettier/**` + - `dependabot/**` +- Paths are not ignored (excludes `docs/**`, `README.md`, `.github/**`) +- Manually via `workflow_dispatch` + +## Workflow Details + +### Jobs + +#### `deploy` +- **Runner**: `ubuntu-latest` +- **Purpose**: Deploys Maven snapshot artifacts to the configured repository + +### Steps + +1. **Checkout code** + - Uses `actions/checkout@v4` + - Checks out the repository code + +2. **Deploy Maven Snapshot** + - Uses `netcracker/qubership-workflow-hub/actions/maven-snapshot-deploy@v1.0.4` + - Deploys snapshot artifacts to the specified target store + +## Configuration + +### Maven Snapshot Deploy Settings +- **Java version**: 21 +- **Target store**: 'github' (or 'central' for Maven Central repository) +- **Maven command**: 'deploy' (default) +- **Additional Maven args**: Configurable additional arguments +- **Maven username**: Uses `github.actor` for GitHub packages +- **Maven token**: Uses `github.token` for GitHub packages + +### Optional Configuration (for Maven Central) +- **Maven username**: `${{ secrets.MAVEN_USER }}` +- **Maven token**: `${{ secrets.MAVEN_PASSWORD }}` +- **GPG private key**: `${{ secrets.MAVEN_GPG_PRIVATE_KEY }}` +- **GPG passphrase**: `${{ secrets.MAVEN_GPG_PASSPHRASE }}` + +### Permissions +- `packages: write` - Required for GitHub packages deployment +- `contents: read` - For reading repository contents + +## Usage + +This workflow is particularly useful for: +- Continuous deployment of development builds +- Testing Maven artifacts before release +- Providing snapshot versions for testing +- Automating deployment to GitHub packages or Maven Central +- Supporting development workflows with immediate artifact availability + +## Features + +- **Smart triggering**: Only deploys from development branches +- **Path filtering**: Ignores documentation and configuration changes +- **Multiple targets**: Supports both GitHub packages and Maven Central +- **GPG signing**: Supports signed artifacts for Maven Central +- **Configurable Maven**: Allows custom Maven commands and arguments +- **Automatic versioning**: Handles snapshot versioning automatically + +## Categories +- Automation +- Maven +- Utilities + +## Labels +- maven +- snapshot +- deploy +- continuous-deployment diff --git a/.github/maven-snapshot-deploy.properties.json b/.github/maven-snapshot-deploy.properties.json new file mode 100644 index 0000000..d7654bd --- /dev/null +++ b/.github/maven-snapshot-deploy.properties.json @@ -0,0 +1,9 @@ +{ + "name": "Qubership Maven snapshot deploy", + "description": "Deploy snapshot versions of maven artifacts to Maven Central or GitHub packages.", + "categories": [ + "Automation", + "Maven", + "utilities" + ] +} diff --git a/.github/maven-snapshot-deploy.yaml b/.github/maven-snapshot-deploy.yaml new file mode 100644 index 0000000..8f8328f --- /dev/null +++ b/.github/maven-snapshot-deploy.yaml @@ -0,0 +1,45 @@ +--- + +# This workflow is used to deploy Maven snapshot artifacts to GitHub packages or Maven Central repository. +# It is triggered on pushes to branches other than main and release branches. +# The workflow uses the `netcracker/qubership-workflow-hub/actions/maven-snapshot-deploy` action to perform the deployment. +# Please read the documentation on how to configure pom.xml for the deployment to work properly: +# https://github.com/netcracker/.github/blob/main/docs/maven-publish-pom-preparation_doc.md + +name: Maven Deploy Snapshot + +on: + push: + branches-ignore: + - "main" + - "**release*" + - "prettier/**" + - "dependabot/**" + paths-ignore: + - "docs/**" + - "README.md" + - ".github/**" + workflow_dispatch: {} +permissions: + packages: write # Required for GitHub packages deployment. For maven central deployment it can be ommited + contents: read +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + + - name: Deploy Maven Snapshot + uses: netcracker/qubership-workflow-hub/actions/maven-snapshot-deploy@v2.0.0 + with: + java-version: '21' # Specify the Java version to use for the build + target-store: 'github' # or 'central' for Maven Central repository + # maven-command: 'package' # Relevant for action versions > v1.0.3 or main. By default maven-command == deploy + additional-mvn-args: '' # Additional arguments to pass to mvn command + maven-username: ${{ github.actor }} # For maven central repository it would be ${{ secrets.MAVEN_USER }} + maven-token: ${{ github.token }} # For maven central repository it would be ${{ secrets.MAVEN_PASSWORD}} + # gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} # Organization level secret. Already set for Netcracker. Required only if target-store is 'central' + # gpg-passphrase: ${{ secrets.MAVEN_GPG_PASSPHRASE }} # Organization level secret. Already set for Netcracker. Required only if target-store is 'central' diff --git a/.github/metadata-config.yml b/.github/metadata-config.yml new file mode 100644 index 0000000..e701dad --- /dev/null +++ b/.github/metadata-config.yml @@ -0,0 +1,14 @@ +branches-template: + - main: "v{{major}}.{{minor}}.{{patch}}-{{date}}" + - "feature/*": "feature-{{ref-name}}-{{timestamp}}.{{github.context.sha}}" + - "release/*": "release-{{ref-name}}-{{timestamp}}.{{github.context.sha}}" + - tag: "v{{major}}.{{minor}}.{{patch}}-{{short-sha}}" + +distribution-tag: + - main: "latest" + - "release/*": "next" + - "feature/*": "beta" + - tag: "stable" + +default-template: "{{ref-name}}-{{timestamp}}-{{runNumber}}" +default-tag: "latest" \ No newline at end of file diff --git a/.github/npm-publish.md b/.github/npm-publish.md new file mode 100644 index 0000000..3c6dd13 --- /dev/null +++ b/.github/npm-publish.md @@ -0,0 +1,130 @@ +# npm Publish + +## Overview + +The npm Publish workflow can be triggered in two ways: +1. **Automatically on push** to any branch (runs in dry-run mode for safety) +2. **Manually via workflow_dispatch** with configurable parameters + +It performs a comprehensive npm package release process including dependency management, version updates, building, testing, and publishing to npm registries. When triggered by push, it automatically runs in dry-run mode to prevent accidental publishing. + +## Trigger + +This workflow can be triggered in two ways: + +1. **Push trigger**: Automatically runs on any push to any branch + - Automatically sets `dry-run: true` for safety + - Uses default parameter values + - Ideal for testing the release process + +2. **Manual trigger**: Can be manually triggered via workflow_dispatch + - Allows full customization of all parameters + - Can set `dry-run: false` for actual publishing + - Suitable for production releases + +## Workflow Details + +### Jobs + +#### `npm-build-publish` +- **Runner**: `ubuntu-latest` +- **Purpose**: Builds and publishes npm packages with comprehensive version management +- **Environment**: Uses `GITHUB_TOKEN` for npm authentication + +### Steps + +1. **Checkout repository** + - Uses `actions/checkout@v4` + - Checks out the repository code + +2. **Show branch** + - Displays the current branch information + +3. **Setup Node.js** + - Uses `actions/setup-node@v4` + - Configures Node.js version and registry settings + - Sets up scope for scoped packages + +4. **Install dependencies** + - Runs `npm ci --legacy-peer-deps` + - Installs project dependencies + +5. **Check if project is a Lerna monorepo** + - Detects if the project uses Lerna for monorepo management + - Sets environment variable for subsequent steps + +6. **Update dependencies (if required)** + - Updates @netcracker dependencies when specified + - Only runs when `update-nc-dependency` is true + +7. **Update package version** + - Updates version in lerna.json (for Lerna projects) + - Updates version in package.json (for standard npm projects) + +## Configuration + +### Required Input Parameters +- `version` (string, required): Release version to publish + +### Optional Input Parameters +- `scope` (string, optional): npm scope (default: "@netcracker") +- `node-version` (string, optional): Node.js version (default: "22.x") +- `registry-url` (string, optional): npm registry URL (default: ``) +- `update-nc-dependency` (boolean, optional): Update @netcracker dependencies (default: false) +- `dry-run` (boolean, optional): Run in dry-run mode (default: false, auto-true on push) +- `dist-tag` (string, optional): npm distribution tag (default: "latest") +- `branch_name` (string, optional): Branch name (default: "main") + +### Permissions +- `contents: write` - For updating package files and committing changes +- `packages: write` - For publishing to npm registries + +### Operation Modes + +#### Push Mode (Automatic) +- **Trigger**: Any push to any branch +- **dry-run**: Automatically set to `true` +- **Parameters**: Use default values +- **Purpose**: Safe testing of the release process + +#### Manual Mode (workflow_dispatch) +- **Trigger**: Manual workflow execution +- **dry-run**: Configurable (default: `false`) +- **Parameters**: Fully customizable +- **Purpose**: Production releases with custom configuration + +## Usage + +This workflow is particularly useful for: +- **Testing release process**: Automatically runs on every push in safe dry-run mode +- **Publishing npm packages**: Manual execution for actual releases +- **Managing Lerna monorepo releases**: Supports both standard and monorepo projects +- **Automating version updates**: Handles dependency and version management +- **Ensuring package quality**: Builds and tests before publishing +- **Supporting scoped packages**: Configurable npm scope support +- **Safe development workflow**: Prevents accidental publishing during development + +## Features + +- **Dual trigger modes**: Automatic push trigger and manual workflow dispatch +- **Safety-first approach**: Automatic dry-run mode on push to prevent accidental publishing +- **Lerna support**: Handles both standard npm and Lerna monorepo projects +- **Dependency management**: Updates @netcracker dependencies when needed +- **Version management**: Automatically updates package versions +- **Multiple registries**: Supports GitHub Packages and npm registry +- **Scoped packages**: Supports scoped package publishing +- **Distribution tags**: Configurable npm distribution tags +- **Comprehensive testing**: Builds and tests before publishing +- **Flexible configuration**: Full parameter customization for manual execution + +## Categories +- JavaScript +- Node.js +- Automation +- npm + +## Labels +- npm +- publish +- JavaScript +- Node.js diff --git a/.github/npm-publish.properties.json b/.github/npm-publish.properties.json new file mode 100644 index 0000000..59b4034 --- /dev/null +++ b/.github/npm-publish.properties.json @@ -0,0 +1,13 @@ +{ + "name": "Qubership NPM Publish", + "description": "NPM Publish workflow template. It can be used to publish NPM packages to GitHub Packages or NPM registry.", + "categories": [ + "JavaScript", + "Node.js", + "Automation", + "NPM" + ], + "filePatterns": [ + "^package.json" + ] +} diff --git a/.github/npm-publish.yaml b/.github/npm-publish.yaml new file mode 100644 index 0000000..309c542 --- /dev/null +++ b/.github/npm-publish.yaml @@ -0,0 +1,59 @@ +name: Publish NPM package + +run-name: NPM Package${{ (github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.dry-run)) && ' - Test' || ' - Publish' }}${{ (github.event_name == 'workflow_dispatch' && !inputs.dry-run && inputs.version) && format(' {0}', inputs.version) || '' }} + +on: + push: + branches: + - '**' + workflow_dispatch: + inputs: + version: + description: 'Release version for NPM (e.g., 1.0.0)' + required: false + type: string + scope: + description: 'NPM scope for the package' + required: false + type: string + default: '@netcracker' + node-version: + required: false + type: string + default: "22.x" + registry-url: + required: false + type: string + default: "https://npm.pkg.github.com" + update-nc-dependency: + required: false + type: boolean + default: false + dry-run: + description: 'Run in dry-run mode (no actual publishing)' + required: false + type: boolean + default: false + npm-dist-tag: + description: 'NPM distribution tag' + required: false + type: string + default: 'latest' + +permissions: + contents: write + packages: write + +jobs: + npm-publish: + uses: Netcracker/qubership-workflow-hub/.github/workflows/re-npm-publish.yml@main + with: + version: ${{ github.event_name == 'workflow_dispatch' && inputs.version || '' }} + scope: ${{ github.event_name == 'workflow_dispatch' && inputs.scope || '@netcracker' }} + node-version: ${{ github.event_name == 'workflow_dispatch' && inputs.node-version || '22.x' }} + registry-url: ${{ github.event_name == 'workflow_dispatch' && inputs.registry-url || 'https://npm.pkg.github.com' }} + update-nc-dependency: ${{ github.event_name == 'workflow_dispatch' && inputs.update-nc-dependency || false }} + dry-run: ${{ github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.dry-run) }} + dist-tag: ${{ github.event_name == 'workflow_dispatch' && inputs.npm-dist-tag || 'latest' }} + ref: ${{ github.ref_name }} + secrets: inherit diff --git a/.github/npm-release.properties.json b/.github/npm-release.properties.json new file mode 100644 index 0000000..0c3b939 --- /dev/null +++ b/.github/npm-release.properties.json @@ -0,0 +1,13 @@ +{ + "name": "Qubership npm Release", + "description": "npm Release workflow template. It can be used to release npm packages with version management, git tagging, and GitHub releases.", + "categories": [ + "JavaScript", + "Node.js", + "Automation", + "npm" + ], + "filePatterns": [ + "^package.json" + ] +} diff --git a/.github/npm-release.yaml b/.github/npm-release.yaml new file mode 100644 index 0000000..0d6f512 --- /dev/null +++ b/.github/npm-release.yaml @@ -0,0 +1,147 @@ +--- + +# This GitHub Actions workflow is triggered manually via workflow_dispatch with configurable parameters. +# +# The workflow performs a comprehensive npm package release process including: +# 1. Tag validation (prevents duplicate releases) +# 2. Test execution (dry-run mode for validation) +# 3. Git tag creation +# 4. Package publishing to npm registry +# 5. GitHub release creation +# +# The workflow delegates the actual npm publishing process to the re-npm-publish.yml workflow +# from the qubership-workflow-hub repository, which performs the following tasks: +# 1. Checks out the repository. +# 2. Sets up Node.js environment. +# 3. Installs dependencies. +# 4. Detects if the project is a Lerna monorepo. +# 5. Updates dependencies if required. +# 6. Updates package version in package.json or lerna.json. +# 7. Builds the project. +# 8. Runs tests. +# 9. Commits and pushes changes. +# 10. Publishes the package to npm registry. + +# To make it work for your project, you need to adjust the package.json and add configuration file for GitHub release. +# Please find detailed instructions: +# https://github.com/netcracker/qubership-workflow-hub?tab=readme-ov-file#npm-project-release-workflow +# +# Note: This workflow is designed for production releases and should be triggered manually +# when you're ready to publish a new version. + +name: Release NPM package + +run-name: Release NPM Package${{ (inputs.dry-run && ' - test') || ' - release' }}${{ (!inputs.dry-run && inputs.version) && format(' {0}', inputs.version) || '' }} + +on: + workflow_dispatch: + inputs: + version: + description: 'Release version for npm (e.g., 1.0.0)' + required: false + type: string + scope: + description: 'npm scope for the package' + required: false + type: string + default: '@netcracker' + node-version: + required: false + type: string + default: "22.x" + registry-url: + required: false + type: string + default: "https://npm.pkg.github.com" + update-nc-dependency: + required: false + type: boolean + default: false + dry-run: + description: 'Run in dry-run mode (no actual publishing)' + required: false + type: boolean + default: false + npm-dist-tag: + description: 'npm distribution tag' + required: false + type: string + default: 'latest' + +permissions: + contents: write + packages: write + +jobs: + check-tag: + if: ${{ !inputs.dry-run }} + runs-on: ubuntu-latest + steps: + - name: Input parameters + run: | + echo "Version: ${{ github.event.inputs.version }}" >> $GITHUB_STEP_SUMMARY + + - name: Checkout code + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Check if tag exists + id: check_tag + uses: netcracker/qubership-workflow-hub/actions/tag-checker@v2.0.0 + with: + tag: 'v${{ github.event.inputs.version }}' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Output result + run: | + echo "Tag exists: ${{ steps.check_tag.outputs.exists }}" + echo "Tag name: v${{ github.event.inputs.version }}" + + - name: Fail if tag exists + if: steps.check_tag.outputs.exists == 'true' + run: | + echo "Tag already exists: v${{ github.event.inputs.version }}" >> $GITHUB_STEP_SUMMARY + echo "Tag already exists: v${{ github.event.inputs.version }}" + exit 1 + + npm-test: + needs: [check-tag] + if: always() + uses: Netcracker/qubership-workflow-hub/.github/workflows/re-npm-publish.yml@main + with: + version: '' + dry-run: true + secrets: inherit + + npm-publish: + if: ${{ !inputs.dry-run }} + needs: [npm-test] + uses: Netcracker/qubership-workflow-hub/.github/workflows/re-npm-publish.yml@main + with: + version: ${{ inputs.version }} + scope: ${{ inputs.scope }} + node-version: ${{ inputs.node-version }} + registry-url: ${{ inputs.registry-url }} + update-nc-dependency: ${{ inputs.update-nc-dependency }} + dry-run: ${{ inputs.dry-run }} + dist-tag: ${{ inputs.npm-dist-tag }} + ref: ${{ github.ref_name }} + secrets: inherit + + tag: + if: ${{ !inputs.dry-run }} + needs: [npm-publish] + uses: netcracker/qubership-workflow-hub/.github/workflows/tag-creator.yml@v2.0.0 + with: + tag-name: "v${{ github.event.inputs.version }}" + + github-release: + if: ${{ !inputs.dry-run }} + needs: [tag] + uses: netcracker/qubership-workflow-hub/.github/workflows/release-drafter.yml@v2.0.0 + with: + version: ${{ github.event.inputs.version }} + publish: false diff --git a/.github/ossf-scorecard.md b/.github/ossf-scorecard.md new file mode 100644 index 0000000..a62784c --- /dev/null +++ b/.github/ossf-scorecard.md @@ -0,0 +1,86 @@ +# OSSF Scorecard + +## Overview + +The OSSF Scorecard workflow performs supply-chain security analysis using the Open Source Security Foundation (OSSF) Scorecard tool. It evaluates repositories for security best practices and provides detailed security scoring and recommendations. + +## Trigger + +This workflow is triggered when: +- Branch protection rules are created or deleted +- Scheduled weekly on Fridays at 20:26 UTC +- Code is pushed to the `main` branch + +## Workflow Details + +### Jobs + +#### `analysis` +- **Runner**: `ubuntu-latest` +- **Purpose**: Performs comprehensive security analysis using OSSF Scorecard +- **Condition**: Only runs on default branch or pull requests + +### Steps + +1. **Checkout code** + - Uses `actions/checkout@v4.2.2` + - Checks out the repository code + - Disables credential persistence for security + +2. **Run analysis** + - Uses `ossf/scorecard-action@v2.4.1` + - Performs security analysis and generates SARIF report + - Configurable authentication and publishing options + +3. **Upload artifact** + - Uses `actions/upload-artifact@v4.6.1` + - Uploads SARIF results as workflow artifacts + - Retention period: 5 days + +4. **Upload to code-scanning** + - Uses `github/codeql-action/upload-sarif@v3.29.0` + - Uploads results to GitHub's code scanning dashboard + +## Configuration + +### Analysis Settings +- **Results format**: SARIF (Static Analysis Results Interchange Format) +- **Results file**: `results.sarif` +- **Publish results**: Disabled (can be enabled for public repositories) +- **File mode**: Optional git mode for repositories with .gitattributes + +### Optional Authentication +- **Repository token**: `${{ secrets.SCORECARD_TOKEN }}` (for private repositories or branch protection checks) + +### Permissions +- **Default**: `read-all` (read-only access) +- **Security events**: `write` (for uploading to code scanning) +- **ID token**: `write` (for publishing results and badges) + +## Usage + +This workflow is particularly useful for: +- Evaluating repository security posture +- Identifying security vulnerabilities and risks +- Monitoring security practices over time +- Providing security scoring and recommendations +- Integrating with GitHub's code scanning dashboard + +## Security Features + +- **Branch protection analysis**: Evaluates branch protection rules +- **Maintenance checks**: Ensures repositories are actively maintained +- **Supply chain security**: Identifies supply chain vulnerabilities +- **Comprehensive scoring**: Provides detailed security metrics +- **Code scanning integration**: Uploads results to GitHub's security dashboard + +## Categories +- Security +- Compliance +- Monitoring + +## Labels +- security +- scorecard +- ossf +- supply-chain diff --git a/.github/ossf-scorecard.yaml b/.github/ossf-scorecard.yaml new file mode 100644 index 0000000..d699821 --- /dev/null +++ b/.github/ossf-scorecard.yaml @@ -0,0 +1,77 @@ +# This workflow uses actions that are not certified by GitHub. They are provided +# by a third-party and are governed by separate terms of service, privacy +# policy, and support documentation. + +name: Scorecard supply-chain security +on: + # For Branch-Protection check. Only the default branch is supported. See + # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection + branch_protection_rule: + types: [created, deleted] + # To guarantee Maintained check is occasionally updated. See + # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained + schedule: + - cron: '26 20 * * 5' + +# Declare default permissions as read only. +permissions: read-all + +jobs: + analysis: + name: Scorecard analysis + runs-on: ubuntu-latest + # `publish_results: true` only works when run from the default branch. conditional can be removed if disabled. + if: github.event.repository.default_branch == github.ref_name || github.event_name == 'pull_request' + permissions: + # Needed to upload the results to code-scanning dashboard. + security-events: write + # Needed to publish results and get a badge (see publish_results below). + id-token: write + # Uncomment the permissions below if installing in a private repository. + # contents: read + # actions: read + + steps: + - name: "Checkout code" + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + + - name: "Run analysis" + uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2 + with: + results_file: results.sarif + results_format: sarif + # (Optional) "write" PAT token. Uncomment the `repo_token` line below if: + # - you want to enable the Branch-Protection check on a *public* repository, or + # - you are installing Scorecard on a *private* repository + # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action?tab=readme-ov-file#authentication-with-fine-grained-pat-optional. + # repo_token: ${{ secrets.SCORECARD_TOKEN }} + + # Public repositories: + # - Publish results to OpenSSF REST API for easy access by consumers + # - Allows the repository to include the Scorecard badge. + # - See https://github.com/ossf/scorecard-action#publishing-results. + # For private repositories: + # - `publish_results` will always be set to `false`, regardless + # of the value entered here. + publish_results: false + + # (Optional) Uncomment file_mode if you have a .gitattributes with files marked export-ignore + # file_mode: git + + # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF + # format to the repository Actions tab. + - name: "Upload artifact" + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: SARIF file + path: results.sarif + retention-days: 5 + + # Upload the results to GitHub's code scanning dashboard (optional). + # Commenting out will disable upload of results to your repo's Code Scanning dashboard + - name: "Upload to code-scanning" + uses: github/codeql-action/upload-sarif@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # v3.30.6 + with: + sarif_file: results.sarif diff --git a/.github/pack-42fd6950d1f9ec078d087e128df936bb6d116784.idx b/.github/pack-42fd6950d1f9ec078d087e128df936bb6d116784.idx new file mode 100644 index 0000000..dcc70c8 Binary files /dev/null and b/.github/pack-42fd6950d1f9ec078d087e128df936bb6d116784.idx differ diff --git a/.github/pack-42fd6950d1f9ec078d087e128df936bb6d116784.pack b/.github/pack-42fd6950d1f9ec078d087e128df936bb6d116784.pack new file mode 100644 index 0000000..4bd0393 Binary files /dev/null and b/.github/pack-42fd6950d1f9ec078d087e128df936bb6d116784.pack differ diff --git a/.github/pack-42fd6950d1f9ec078d087e128df936bb6d116784.rev b/.github/pack-42fd6950d1f9ec078d087e128df936bb6d116784.rev new file mode 100644 index 0000000..8f70240 Binary files /dev/null and b/.github/pack-42fd6950d1f9ec078d087e128df936bb6d116784.rev differ diff --git a/.github/post-update.sample b/.github/post-update.sample new file mode 100755 index 0000000..ec17ec1 --- /dev/null +++ b/.github/post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/.github/pr-assigner-config.yml b/.github/pr-assigner-config.yml new file mode 100644 index 0000000..35ffad2 --- /dev/null +++ b/.github/pr-assigner-config.yml @@ -0,0 +1,7 @@ +# List of users who can be assigned to a pull request +assignees: + - user_name1 + - user_name2 + - user_name3 +# How many users from the assigneeslist should be assigned +count: 2 diff --git a/.github/pr-assigner.md b/.github/pr-assigner.md new file mode 100644 index 0000000..06e442a --- /dev/null +++ b/.github/pr-assigner.md @@ -0,0 +1,78 @@ +# PR Assigner + +## Overview + +The PR Assigner workflow automatically assigns reviewers to pull requests based on configuration files or CODEOWNERS. It uses the PR Assigner GitHub Action to streamline the review process and ensure appropriate reviewers are assigned to each pull request. + +## Trigger + +This workflow is triggered when: +- A pull request is opened +- A pull request is reopened +- A pull request is synchronized (updated) + +## Workflow Details + +### Jobs + +#### `assign` +- **Runner**: `ubuntu-latest` +- **Purpose**: Automatically assigns reviewers to pull requests +- **Uses**: `netcracker/qubership-workflow-hub/actions/pr-assigner@v1.0.4` + +#### `warning-message` +- **Runner**: `ubuntu-latest` +- **Purpose**: Displays warning for pull requests from forks +- **Condition**: Only runs for pull requests from external forks + +### Steps + +#### assign Job +1. **Checkout Repository** + - Uses `actions/checkout@v4` + - Checks out the repository code + +2. **PR Auto-Assignment** + - Uses the PR assigner action + - Reads configuration from [`.github/pr-assigner-config.yml`](../../config/examples/pr-assigner-config.yml) + - Shuffles assignments with factor 2 for distribution + +#### warning-message Job +1. **Warning** + - Displays warning message for fork pull requests + - Informs that automatic assignment is not possible for forks + +## Configuration + +### Required Files +- [`.github/pr-assigner-config.yml`](../../config/examples/pr-assigner-config.yml): Configuration file for PR assignment rules + +### Assignment Settings +- **Configuration path**: `.github/pr-assigner-config.yml` +- **Shuffle factor**: 2 (distributes assignments evenly) +- **Assignment method**: Based on configuration file or CODEOWNERS + +### Permissions +- `pull-requests: write` - For assigning reviewers to pull requests +- `contents: read` - For reading configuration files + +## Usage + +This workflow is particularly useful for: +- Automating reviewer assignment for pull requests +- Ensuring consistent review coverage +- Reducing manual overhead in pull request management +- Distributing review workload evenly among team members +- Maintaining review quality through appropriate assignments + +## Features + +- **Automatic assignment**: Assigns reviewers based on configuration +- **Fork detection**: Handles pull requests from external forks appropriately +- **Shuffle distribution**: Ensures even distribution of review assignments +- **Configuration-based**: Uses flexible configuration files +- **CODEOWNERS integration**: Can use existing CODEOWNERS files + +## Categories +- Automation +- Pull Request diff --git a/.github/pr-assigner.properties.json b/.github/pr-assigner.properties.json new file mode 100644 index 0000000..eb6ecfb --- /dev/null +++ b/.github/pr-assigner.properties.json @@ -0,0 +1,11 @@ +{ + "name": "Qubership PR Auto-Assignment", + "description": "GitHub Actions workflow template that uses PR Assigner GitHub Action and automatically assigns reviewers to pull requests based on a configuration file (.github/assigne-config.yml) or the CODEOWNERS file.", + "categories": [ + "Automation", + "Pull Request" + ], + "labels": [ + "preview" + ] +} diff --git a/.github/pr-assigner.yml b/.github/pr-assigner.yml new file mode 100644 index 0000000..66965ff --- /dev/null +++ b/.github/pr-assigner.yml @@ -0,0 +1,31 @@ +name: PR Auto-Assignment +run-name: "Assigning reviewers for PR #${{ github.event.pull_request.number }}" +on: + pull_request_target: + types: [opened, reopened, synchronize] + branches: + - main + +permissions: + pull-requests: write + contents: read + +jobs: + pr-auto-assign: + runs-on: ubuntu-latest + + steps: + - name: Check if PR is from a fork + run: | + if [ "${{ github.event.pull_request.head.repo.full_name }}" != "${{ github.event.pull_request.base.repo.full_name }}" ]; then + echo "⚠️ Pull request is from a fork — skipping assignee assignment (no write permissions)." + exit 0 + fi + + - uses: actions/checkout@v5 + with: + persist-credentials: false + + - uses: netcracker/qubership-workflow-hub/actions/pr-assigner@b575bad3a0959c4e883bc34f9d055ff07fde2dbd #2.0.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/pr-cleaner.yaml b/.github/pr-cleaner.yaml new file mode 100644 index 0000000..6947834 --- /dev/null +++ b/.github/pr-cleaner.yaml @@ -0,0 +1,102 @@ +name: Pull Request Cleaner + +on: + workflow_dispatch: # Allows manual triggering of the workflow + inputs: + org_name: + description: >- + Name of GitHub organization. + required: true + default: "Netcracker" + branch_name_prefix: + description: >- + Prefix of the branch name to be deleted. + required: true + default: "bot/" + branch_delete: + description: >- + Whether to delete the branch after closing the PR. + If true, the branch will be deleted. + required: false + default: "true" + remove_orphant_branches: + description: >- + Whether to remove orphan branches. + If true, the branches not related to PRs will be removed. + required: false + default: "false" + target_repo: + description: >- + Name of the target repository. + If empty all organization repos will be updated. + required: false + comment: + description: >- + Comment to be added when closing the PR. + required: true + default: "This PR is closed as part of the cleanup process." +permissions: + contents: read +jobs: + pull_request_cleanup: + runs-on: ubuntu-latest + + steps: + # Step 1: Checkout the repository + - name: Checkout Repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + + # Step 2 Setup Pull Request Cleaner + - name: Setup Pull Request Cleaner + env: + GITHUB_TOKEN: ${{ secrets.GH_ACCESS_TOKEN }} + ORG_NAME: ${{ github.event.inputs.org_name }} + TARGET_REPO: ${{ github.event.inputs.target_repo }} + BRANCH_NAME_PREFIX: ${{ github.event.inputs.branch_name_prefix }} + BRANCH_DELETE: ${{ github.event.inputs.branch_delete }} + COMMENT: ${{ github.event.inputs.comment }} + REMOVE_ORPHANT_BRANCHES: ${{ github.event.inputs.remove_orphant_branches }} + run: | + if [ -n "$TARGET_REPO" ]; then + repos="$TARGET_REPO" + else + repos=$(gh repo list "$ORG_NAME" --visibility public --limit 1000 --json name --jq '.[].name') + fi + + for repo in $repos; do + echo "Processing repository: $repo" + + # Get open pull requests with branch names containing the specified prefix + prs=$(gh pr list --repo "$ORG_NAME/$repo" --state open --json number,headRefName \ + --jq ".[] | select(.headRefName | contains(\"$BRANCH_NAME_PREFIX\")) | .number") + + for pr in $prs; do + echo "Closing PR #$pr in $repo" + + # Close the pull request with a comment + if [ "$BRANCH_DELETE" = "true" ]; then + gh pr close "$pr" --repo "$ORG_NAME/$repo" \ + --delete-branch --comment "$COMMENT" + else + gh pr close "$pr" --repo "$ORG_NAME/$repo" \ + --comment "$COMMENT" + fi + done + + # Remove orphan branches if specified + if [ "$REMOVE_ORPHANT_BRANCHES" = "true" ] && [ -n "$BRANCH_NAME_PREFIX" ]; then + echo "Removing orphan branches in $repo with prefix '$BRANCH_NAME_PREFIX'" + orphan_branches=$(gh api repos/$ORG_NAME/$repo/branches \ + --jq ".[] | select(.name | startswith(\"$BRANCH_NAME_PREFIX\")) | .name") + + for branch in $orphan_branches; do + echo "Deleting orphan branch: $branch" + gh api -X DELETE repos/$ORG_NAME/$repo/git/refs/heads/$branch + sleep 3s + done + fi + done + + echo "Pull request cleanup completed." diff --git a/.github/pr-conventional-commits.md b/.github/pr-conventional-commits.md new file mode 100644 index 0000000..c221d2f --- /dev/null +++ b/.github/pr-conventional-commits.md @@ -0,0 +1,7 @@ +# Conventional Commits PR Check + +The workflow will check commits in pull request if they follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) strategy. + +More info on underlying GitHub Action can be found here [Conventional Commits GitHub Action](https://github.com/webiny/action-conventional-commits) + +**To add the workflow into your repository** copy the [prepared file](https://github.com/Netcracker/.github/blob/main/workflow-templates/pr-conventional-commits.yaml) into `.github/workflows` directory of your repository. diff --git a/.github/pr-conventional-commits.properties.json b/.github/pr-conventional-commits.properties.json new file mode 100644 index 0000000..08b32bc --- /dev/null +++ b/.github/pr-conventional-commits.properties.json @@ -0,0 +1,8 @@ +{ + "name": "Qubership Conventional Commits PR Check", + "description": "Conventional Commits PR Check workflow template. It can be used to automatically check if the commits in PR have followed the conventional commits messages.", + "categories": [ + "Automation" + ], + "labels": [ "preview"] +} diff --git a/.github/pr-conventional-commits.yaml b/.github/pr-conventional-commits.yaml new file mode 100644 index 0000000..1056dc9 --- /dev/null +++ b/.github/pr-conventional-commits.yaml @@ -0,0 +1,23 @@ +--- + +name: Conventional Commits PR Check + +on: + pull_request: + types: + - opened + - edited + - synchronize + +permissions: + pull-requests: read +jobs: + build: + name: Conventional Commits + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + with: + persist-credentials: false + + - uses: webiny/action-conventional-commits@8bc41ff4e7d423d56fa4905f6ff79209a78776c7 #v1.3.0 diff --git a/.github/pr-lint-title.md b/.github/pr-lint-title.md new file mode 100644 index 0000000..41ba698 --- /dev/null +++ b/.github/pr-lint-title.md @@ -0,0 +1,7 @@ +# Lint PR Title + +The workflow will check pull request title if it follows [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) strategy. + +More info on underlying GitHub Action can be found here [Semantic Pull Request](https://github.com/amannn/action-semantic-pull-request). + +**To add the workflow into your repository** copy the [prepared file](https://github.com/Netcracker/.github/blob/main/workflow-templates/pr-lint-title.yaml) into `.github/workflows` directory of your repository. diff --git a/.github/pr-lint-title.properties.json b/.github/pr-lint-title.properties.json new file mode 100644 index 0000000..6cf05ab --- /dev/null +++ b/.github/pr-lint-title.properties.json @@ -0,0 +1,8 @@ +{ + "name": "Qubership Lint PR Title", + "description": "Lint PR Title workflow template. It can be used to automatically check if PR title follow the conventional commits starategy.", + "categories": [ + "Automation" + ], + "labels": [ "preview"] +} diff --git a/.github/pr-lint-title.yaml b/.github/pr-lint-title.yaml new file mode 100644 index 0000000..ce7e52b --- /dev/null +++ b/.github/pr-lint-title.yaml @@ -0,0 +1,23 @@ +--- + +name: "Lint PR Title" + +on: + pull_request: + types: + - opened + - edited + - synchronize + - reopened + +permissions: + pull-requests: read + +jobs: + main: + name: Validate PR title + runs-on: ubuntu-latest + steps: + - uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1 + env: + GITHUB_TOKEN: ${{ github.token }} diff --git a/.github/pre-applypatch.sample b/.github/pre-applypatch.sample new file mode 100755 index 0000000..4142082 --- /dev/null +++ b/.github/pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +precommit="$(git rev-parse --git-path hooks/pre-commit)" +test -x "$precommit" && exec "$precommit" ${1+"$@"} +: diff --git a/.github/pre-commit.sample b/.github/pre-commit.sample new file mode 100755 index 0000000..29ed5ee --- /dev/null +++ b/.github/pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=$(git hash-object -t tree /dev/null) +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --type=bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff-index --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/.github/pre-merge-commit.sample b/.github/pre-merge-commit.sample new file mode 100755 index 0000000..399eab1 --- /dev/null +++ b/.github/pre-merge-commit.sample @@ -0,0 +1,13 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git merge" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message to +# stderr if it wants to stop the merge commit. +# +# To enable this hook, rename this file to "pre-merge-commit". + +. git-sh-setup +test -x "$GIT_DIR/hooks/pre-commit" && + exec "$GIT_DIR/hooks/pre-commit" +: diff --git a/.github/pre-push.sample b/.github/pre-push.sample new file mode 100755 index 0000000..4ce688d --- /dev/null +++ b/.github/pre-push.sample @@ -0,0 +1,53 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +zero=$(git hash-object --stdin &2 "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/.github/pre-rebase.sample b/.github/pre-rebase.sample new file mode 100755 index 0000000..6cbef5c --- /dev/null +++ b/.github/pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up to date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/.github/pre-receive.sample b/.github/pre-receive.sample new file mode 100755 index 0000000..a1fd29e --- /dev/null +++ b/.github/pre-receive.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to make use of push options. +# The example simply echoes all push options that start with 'echoback=' +# and rejects all pushes when the "reject" push option is used. +# +# To enable this hook, rename this file to "pre-receive". + +if test -n "$GIT_PUSH_OPTION_COUNT" +then + i=0 + while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" + do + eval "value=\$GIT_PUSH_OPTION_$i" + case "$value" in + echoback=*) + echo "echo from the pre-receive-hook: ${value#*=}" >&2 + ;; + reject) + exit 1 + esac + i=$((i + 1)) + done +fi diff --git a/.github/prepare-commit-msg.sample b/.github/prepare-commit-msg.sample new file mode 100755 index 0000000..10fa14c --- /dev/null +++ b/.github/prepare-commit-msg.sample @@ -0,0 +1,42 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first one removes the +# "# Please enter the commit message..." help message. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +COMMIT_MSG_FILE=$1 +COMMIT_SOURCE=$2 +SHA1=$3 + +/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" + +# case "$COMMIT_SOURCE,$SHA1" in +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; +# *) ;; +# esac + +# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" +# if test -z "$COMMIT_SOURCE" +# then +# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" +# fi diff --git a/.github/profanity-filter.md b/.github/profanity-filter.md new file mode 100644 index 0000000..6edca0b --- /dev/null +++ b/.github/profanity-filter.md @@ -0,0 +1,7 @@ +# Profanity filter + +The action to check PRs/issues comments on profany words. + +> More info about underlying GitHub Action can be found here [profanity-filter](https://github.com/IEvangelist/profanity-filter) + +To add the profanity filter into your repository just copy the [prepared file](https://github.com/Netcracker/.github/blob/main/workflow-templates/profanity-filter.yaml) into `.github/workflows` directory of your repository. diff --git a/.github/profanity-filter.properties.json b/.github/profanity-filter.properties.json new file mode 100644 index 0000000..26841d5 --- /dev/null +++ b/.github/profanity-filter.properties.json @@ -0,0 +1,9 @@ +{ + "name": "Qubership Profanity filter", + "description": "Profanity filter workflow template. It can be used to automatically check for profanity in the PR, issues, issue comments.", + + "categories": [ + "Automation" + ], + "labels": [ "preview"] +} diff --git a/.github/profanity-filter.yaml b/.github/profanity-filter.yaml new file mode 100644 index 0000000..74926d3 --- /dev/null +++ b/.github/profanity-filter.yaml @@ -0,0 +1,29 @@ +--- +name: Profanity filter + +on: + issue_comment: + types: [created, edited] + issues: + types: [opened, edited, reopened] + pull_request: + types: [opened, edited, reopened] + +permissions: + issues: write + pull-requests: write + +jobs: + apply-filter: + runs-on: ubuntu-latest + steps: + - name: Scan issue or pull request for profanity + # Conditionally run the step if the actor isn't a bot + if: ${{ github.actor != 'dependabot[bot]' && github.actor != 'github-actions[bot]' }} + uses: IEvangelist/profanity-filter@9.07 + id: profanity-filter + with: + token: ${{ secrets.GITHUB_TOKEN }} + # See https://bit.ly/potty-mouth-replacement-strategies + replacement-strategy: middle-asterisk # See Replacement strategy + custom-profane-words-url: https://github.com/Hesham-Elbadawi/list-of-banned-words/raw/refs/heads/master/ru diff --git a/.github/push-to-checkout.sample b/.github/push-to-checkout.sample new file mode 100755 index 0000000..af5a0c0 --- /dev/null +++ b/.github/push-to-checkout.sample @@ -0,0 +1,78 @@ +#!/bin/sh + +# An example hook script to update a checked-out tree on a git push. +# +# This hook is invoked by git-receive-pack(1) when it reacts to git +# push and updates reference(s) in its repository, and when the push +# tries to update the branch that is currently checked out and the +# receive.denyCurrentBranch configuration variable is set to +# updateInstead. +# +# By default, such a push is refused if the working tree and the index +# of the remote repository has any difference from the currently +# checked out commit; when both the working tree and the index match +# the current commit, they are updated to match the newly pushed tip +# of the branch. This hook is to be used to override the default +# behaviour; however the code below reimplements the default behaviour +# as a starting point for convenient modification. +# +# The hook receives the commit with which the tip of the current +# branch is going to be updated: +commit=$1 + +# It can exit with a non-zero status to refuse the push (when it does +# so, it must not modify the index or the working tree). +die () { + echo >&2 "$*" + exit 1 +} + +# Or it can make any necessary changes to the working tree and to the +# index to bring them to the desired state when the tip of the current +# branch is updated to the new commit, and exit with a zero status. +# +# For example, the hook can simply run git read-tree -u -m HEAD "$1" +# in order to emulate git fetch that is run in the reverse direction +# with git push, as the two-tree form of git read-tree -u -m is +# essentially the same as git switch or git checkout that switches +# branches while keeping the local changes in the working tree that do +# not interfere with the difference between the branches. + +# The below is a more-or-less exact translation to shell of the C code +# for the default behaviour for git's push-to-checkout hook defined in +# the push_to_deploy() function in builtin/receive-pack.c. +# +# Note that the hook will be executed from the repository directory, +# not from the working tree, so if you want to perform operations on +# the working tree, you will have to adapt your code accordingly, e.g. +# by adding "cd .." or using relative paths. + +if ! git update-index -q --ignore-submodules --refresh +then + die "Up-to-date check failed" +fi + +if ! git diff-files --quiet --ignore-submodules -- +then + die "Working directory has unstaged changes" +fi + +# This is a rough translation of: +# +# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX +if git cat-file -e HEAD 2>/dev/null +then + head=HEAD +else + head=$(git hash-object -t tree --stdin > $GITHUB_STEP_SUMMARY + echo "Version: ${{ github.event.inputs.version }}" >> $GITHUB_STEP_SUMMARY + echo "Python version: ${{ github.event.inputs.python-version }}" >> $GITHUB_STEP_SUMMARY + echo "Poetry version options: ${{ github.event.inputs.poetry-version-options }}" >> $GITHUB_STEP_SUMMARY + echo "Poetry build parameters: ${{ github.event.inputs.poetry-build-params }}" >> $GITHUB_STEP_SUMMARY + echo "Pytest run: ${{ github.event.inputs.pytest-run }}" >> $GITHUB_STEP_SUMMARY + echo "Pytest parameters: ${{ github.event.inputs.pytest-params }}" >> $GITHUB_STEP_SUMMARY + - name: Check if tag exists + if: ${{ inputs.version != '' }} + id: check_tag + uses: netcracker/qubership-workflow-hub/actions/tag-action@v2.0.0 + with: + tag-name: 'v${{ inputs.version }}' + ref: ${{ github.ref }} + create-tag: false + check-tag: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + publish: + runs-on: ubuntu-latest + permissions: + contents: write + needs: [pre-build-checks] + outputs: + published-version: ${{ steps.publish.outputs.release-version }} + steps: + - name: "Prepare app token" + if: ${{ vars.GH_BUMP_VERSION_APP_ID != '' }} + uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4 + id: app-token + with: + app-id: ${{ vars.GH_BUMP_VERSION_APP_ID }} + private-key: ${{ secrets.GH_BUMP_VERSION_APP_KEY }} + - name: "Checkout" + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + token: ${{ steps.app-token.outputs.token || secrets.GITHUB_TOKEN }} + - name: "Setup Python ${{ inputs.python-version }}" + uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 + with: + python-version: ${{ inputs.python-version }} + + - name: "Publish" + id: publish + uses: netcracker/qubership-workflow-hub/actions/poetry-publisher@v2.0.0 + with: + package_version: ${{ inputs.version }} + poetry_version_bump: ${{ inputs.poetry-version-options }} + poetry_build_options: ${{ inputs.poetry-build-params }} + run_pytest: ${{ inputs.pytest-run }} + pytest_options: ${{ inputs.pytest-params }} + publish: "true" + env: + PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }} + - name: "Commit changes" + run: | + git config --global user.email "$GITHUB_ACTOR@users.noreply.github.com" + git config --global user.name "$GITHUB_ACTOR" + git add . + git commit -m "Update version to ${{ steps.publish.outputs.release-version }} for release" + git push -u origin ${{ github.ref }} + + github-release: + permissions: + contents: write + pull-requests: write + needs: [publish] + uses: netcracker/qubership-workflow-hub/.github/workflows/release-drafter.yml@v2.0.0 + with: + version: ${{ needs.publish.outputs.published-version }} + publish: true diff --git a/.github/release-drafter-config.yml b/.github/release-drafter-config.yml new file mode 100644 index 0000000..1687859 --- /dev/null +++ b/.github/release-drafter-config.yml @@ -0,0 +1,49 @@ +name-template: 'v$RESOLVED_VERSION' +tag-template: 'v$RESOLVED_VERSION' + + +categories: + - title: '💥 Breaking Changes' + labels: + - breaking-change + - title: '💡 New Features' + labels: + - feature + - enhancement + - title: '🐞 Bug Fixes' + labels: + - bug + - fix + - bugfix + - title: '⚙️ Technical Debt' + labels: + - refactor + - title: '📝 Documentation' + labels: + - documentation + +change-template: "- (#$NUMBER) $TITLE by @$AUTHOR" + +no-changes-template: 'No significant changes' + +template: | + ## 🚀 Release + + ### What's Changed + $CHANGES + + --- + + **Full Changelog**: https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...v$RESOLVED_VERSION + +version-resolver: + major: + labels: + - major + minor: + labels: + - minor + patch: + labels: + - patch + default: patch diff --git a/.github/repo-list-rabenok.txt b/.github/repo-list-rabenok.txt new file mode 100644 index 0000000..ff2b17f --- /dev/null +++ b/.github/repo-list-rabenok.txt @@ -0,0 +1 @@ +DRNavigator, qubership-consul, qubership-deployment-status-provisioner, qubership-core-blue-green-state-monitor, qubership-core-blue-green-state-monitor-quarkus, qubership-core-config-server, qubership-core-context-propagation, qubership-core-context-propagation-quarkus, qubership-core-control-plane, qubership-core-core-operator, qubership-core-dbaas-agent, qubership-core-error-handling, qubership-core-facade-operator, qubership-core-infra, qubership-core-junit-k8s-extension, qubership-core-lib-go, qubership-core-lib-go-actuator-common, qubership-core-lib-go-bg-kafka, qubership-core-lib-go-bg-state-monitor, pgskipper-pgbackrest-sidecar, pgskipper-replication-controller, pgskipper-dbaas-adapter, pgskipper-operator-core, pgskipper-upgrade, pgskipper-backup-daemon, pgskipper-monitoring-agent, pgskipper-patroni, qubership-hive-metastore, qubership-mistral, qubership-profiler-agent, qubership-mistral-operator, qubership-nosqldb-operator-core, qubership-cql-driver, qubership-kafka, qubership-spark-on-k8s, qubership-mongodb-driver, qubership-core-lib-go-error-handling, qubership-core-lib-go-fiber-server-utils, qubership-core-lib-go-maas-bg-segmentio, qubership-core-lib-go-maas-client, qubership-core-lib-go-maas-core, qubership-av-scan-service, qubership-core-lib-go-maas-segmentio, qubership-core-lib-go-paas-mediation-client, qubership-core-lib-go-rest-utils, qubership-core-lib-go-stomp-websocket, qubership-core-maas-agent, qubership-core-microservice-dependencies, qubership-core-microservice-framework, qubership-core-microservice-framework-extensions, qubership-core-paas-mediation, qubership-core-process-orchestrator, qubership-core-restclient, qubership-core-rest-libraries, qubership-core-site-management, qubership-core-springboot-starter, qubership-core-utils, qubership-dbaas-adapter-core, qubership-rabbitmq, qubership-trino, qubership-maas-client, qubership-airflow, qubership-hue, qubership-maas-client-quarkus, qubership-maas-client-spring, qubership-maas-declarative-client-commons, qubership-maas-declarative-client-quarkus, qubership-maas-declarative-client-spring, kafka, postgres, cassandra, qubership-core-bootstrap, keycloak, postgres-patches, arangodb-patches, keycloak-patches, cassandra-patches, kafka-patches, rabbitmq-patches, consul-patches, qubership-core-test-apps, qubership-profiler-backend \ No newline at end of file diff --git a/.github/sbom-to-release.md b/.github/sbom-to-release.md new file mode 100644 index 0000000..9e7cf89 --- /dev/null +++ b/.github/sbom-to-release.md @@ -0,0 +1,85 @@ +# SBOM to Release + +## Overview + +The SBOM to Release workflow generates Software Bill of Materials (SBOM) files and uploads them to GitHub releases as assets. It uses CycloneDX to create comprehensive SBOM files that document all dependencies and components in the software. + +## Trigger + +This workflow is triggered when: +- A release is published (released event) +- Manually via `workflow_dispatch` with a release tag input + +## Workflow Details + +### Jobs + +#### `generate-sbom` +- **Runner**: `ubuntu-latest` +- **Purpose**: Generates SBOM files and uploads them to GitHub releases + +### Steps + +1. **Set RELEASE_VERSION** + - Determines the release version from the release event or manual input + - Sets environment variable for use in subsequent steps + +2. **Checkout code** + - Uses `actions/checkout@v4` + - Checks out the specific release tag version + +3. **Free some space** + - Removes hosted tool cache to free up disk space + - Ensures sufficient space for SBOM generation + +4. **Generate BOM** + - Uses CycloneDX cdxgen Docker image (v8.6.0) + - Generates SBOM in JSON format + - Includes license information (`FETCH_LICENSE=true`) + - Cleans up Docker images after generation + +5. **Upload SBOM file to GitHub Release** + - Uses `AButler/upload-release-assets@v3.0` + - Uploads the generated SBOM file to the GitHub release + - Uses the repository name and release version in the filename + +## Configuration + +### Input Parameters (Manual Trigger) +- `release-tag` (string, required): Release tag to generate SBOM for + +### SBOM Generation Settings +- **Tool**: CycloneDX cdxgen v8.6.0 +- **Format**: JSON +- **License fetching**: Enabled +- **Output filename**: `{repository-name}_sbom.{version}.json` + +### Permissions +- `contents: write` - For uploading assets to GitHub releases + +## Usage + +This workflow is particularly useful for: +- Generating comprehensive SBOM files for releases +- Documenting all dependencies and components +- Compliance and security auditing +- Supply chain transparency +- License compliance verification + +## Features + +- **Automatic triggering**: Runs automatically when releases are published +- **Manual execution**: Can be triggered manually for specific releases +- **Comprehensive SBOM**: Includes all dependencies and license information +- **Release integration**: Automatically uploads to GitHub releases +- **Space management**: Frees up disk space for large SBOM generation +- **Docker cleanup**: Removes Docker images after generation + +## Categories +- Automation + +## Labels +- sbom +- security +- compliance +- release diff --git a/.github/sbom-to-release.properties.json b/.github/sbom-to-release.properties.json new file mode 100644 index 0000000..120c368 --- /dev/null +++ b/.github/sbom-to-release.properties.json @@ -0,0 +1,8 @@ +{ + "name": "Qubership Generate SBOM file and upload it to GitHub Release", + "description": "Generate SBOM file and upload it to GitHub Release as an asset.", + + "categories": [ + "Automation" + ] +} diff --git a/.github/sbom-to-release.yaml b/.github/sbom-to-release.yaml new file mode 100644 index 0000000..c7f5aaf --- /dev/null +++ b/.github/sbom-to-release.yaml @@ -0,0 +1,47 @@ +name: "Generate SBOM file and upload it to GitHub Release" + +on: + release: + types: [released] + workflow_dispatch: + inputs: + release-tag: + description: "Release tag" + required: true + default: "" +permissions: + contents: write +jobs: + generate-sbom: + runs-on: ubuntu-latest + steps: + - name: "Set RELEASE_VERSION" + id: set-version + run: | + if [ "${{ github.event.release.tag_name }}" != "" ]; then + echo "RELEASE_VERSION=${{ github.event.release.tag_name }}" >> $GITHUB_ENV + else + echo "RELEASE_VERSION=${{ github.event.inputs.release-tag }}" >> $GITHUB_ENV + fi + - name: Checkout code + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + ref: ${{ env.RELEASE_VERSION }} + persist-credentials: false + - name: "Free some space" + run: rm -rf /opt/hostedtoolcache + shell: bash + - name: "Generate BOM" + run: | + cd ${GITHUB_WORKSPACE} + export FETCH_LICENSE=true + docker run --rm -e FETCH_LICENSE=true -v /tmp:/tmp -v $(pwd):/app:rw -t ghcr.io/cyclonedx/cdxgen:v8.6.0 -r /app -p -o /app/${{ github.event.repository.name }}_sbom.${{ env.RELEASE_VERSION }}.json + docker rmi -f $(docker images -aq) + shell: bash + + - name: Upload SBOM file to GitHub Release + uses: AButler/upload-release-assets@v3.0 + with: + files: "**/${{ github.event.repository.name }}_sbom.${{ env.RELEASE_VERSION }}.json" + repo-token: ${{ secrets.GITHUB_TOKEN }} + release-tag: ${{ env.RELEASE_VERSION }} diff --git a/.github/scout-cves.properties.json b/.github/scout-cves.properties.json new file mode 100644 index 0000000..f215a2e --- /dev/null +++ b/.github/scout-cves.properties.json @@ -0,0 +1,8 @@ +{ + "name": "Qubership Docker Scout CVE Scan", + "description": "Scan public Docker images for CVEs with Docker Scout and upload results in SARIF format.", + "categories": [ + "Security", + "Automation" + ] +} \ No newline at end of file diff --git a/.github/scout-cves.yml b/.github/scout-cves.yml new file mode 100644 index 0000000..8185095 --- /dev/null +++ b/.github/scout-cves.yml @@ -0,0 +1,39 @@ +name: Docker Scout CVE Scan + +on: + workflow_dispatch: + inputs: + image: + description: "Public images (sample: nginx:1.27)" + required: true + type: string + +jobs: + scan: + runs-on: ubuntu-latest + permissions: + contents: read + security-events: write + + steps: + - name: Checkout Repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + + - name: Docker login + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USER }} + password: ${{ secrets.DOCKERHUB_RW_TOKEN }} + + - name: Run Docker Scout CVEs + id: scout + uses: docker/scout-action@v1 + with: + command: cves + image: ${{ inputs.image }} + only-severities: critical,high + only-fixed: false + exit-code: true + sarif-file: scout-results.sarif diff --git a/.github/security-scan.properties.json b/.github/security-scan.properties.json new file mode 100644 index 0000000..60505c2 --- /dev/null +++ b/.github/security-scan.properties.json @@ -0,0 +1,8 @@ +{ + "name": "Qubership Security Scan", + "description": "Scan public Docker images or repository source code by Trivy and/or Grype and upload results in SARIF format.", + "categories": [ + "Security", + "Automation" + ] +} \ No newline at end of file diff --git a/.github/security-scan.yml b/.github/security-scan.yml new file mode 100644 index 0000000..fc1e926 --- /dev/null +++ b/.github/security-scan.yml @@ -0,0 +1,59 @@ +name: Security Scan +on: + workflow_dispatch: + inputs: + target: + description: "Scan part" + required: true + default: "docker" + type: choice + options: + - docker + - source + image: + description: "Docker image (for 'docker' target). By default ghcr.io//:latest" + required: false + default: "" + only-high-critical: + description: "Scan only HIGH + CRITICAL" + required: false + default: true + type: boolean + trivy-scan: + description: "Run Trivy scan" + required: false + default: true + type: boolean + grype-scan: + description: "Run Grype scan" + required: false + default: true + type: boolean + continue-on-error: + description: "Continue on error" + required: false + default: true + type: boolean + only-fixed: + description: "Show only fixable vulnerabilities" + required: false + default: true + type: boolean + +permissions: + contents: read + security-events: write + actions: read + packages: read + +jobs: + security-scan: + uses: netcracker/qubership-workflow-hub/.github/workflows/re-security-scan.yml@main + with: + target: ${{ github.event.inputs.target || 'source' }} + image: ${{ github.event.inputs.image || '' }} + only-high-critical: ${{ inputs.only-high-critical}} + trivy-scan: ${{ inputs.trivy-scan }} + grype-scan: ${{ inputs.grype-scan }} + only-fixed: ${{ inputs.only-fixed }} + continue-on-error: ${{ inputs.continue-on-error }} \ No newline at end of file diff --git a/.github/sendemail-validate.sample b/.github/sendemail-validate.sample new file mode 100755 index 0000000..640bcf8 --- /dev/null +++ b/.github/sendemail-validate.sample @@ -0,0 +1,77 @@ +#!/bin/sh + +# An example hook script to validate a patch (and/or patch series) before +# sending it via email. +# +# The hook should exit with non-zero status after issuing an appropriate +# message if it wants to prevent the email(s) from being sent. +# +# To enable this hook, rename this file to "sendemail-validate". +# +# By default, it will only check that the patch(es) can be applied on top of +# the default upstream branch without conflicts in a secondary worktree. After +# validation (successful or not) of the last patch of a series, the worktree +# will be deleted. +# +# The following config variables can be set to change the default remote and +# remote ref that are used to apply the patches against: +# +# sendemail.validateRemote (default: origin) +# sendemail.validateRemoteRef (default: HEAD) +# +# Replace the TODO placeholders with appropriate checks according to your +# needs. + +validate_cover_letter () { + file="$1" + # TODO: Replace with appropriate checks (e.g. spell checking). + true +} + +validate_patch () { + file="$1" + # Ensure that the patch applies without conflicts. + git am -3 "$file" || return + # TODO: Replace with appropriate checks for this patch + # (e.g. checkpatch.pl). + true +} + +validate_series () { + # TODO: Replace with appropriate checks for the whole series + # (e.g. quick build, coding style checks, etc.). + true +} + +# main ------------------------------------------------------------------------- + +if test "$GIT_SENDEMAIL_FILE_COUNTER" = 1 +then + remote=$(git config --default origin --get sendemail.validateRemote) && + ref=$(git config --default HEAD --get sendemail.validateRemoteRef) && + worktree=$(mktemp --tmpdir -d sendemail-validate.XXXXXXX) && + git worktree add -fd --checkout "$worktree" "refs/remotes/$remote/$ref" && + git config --replace-all sendemail.validateWorktree "$worktree" +else + worktree=$(git config --get sendemail.validateWorktree) +fi || { + echo "sendemail-validate: error: failed to prepare worktree" >&2 + exit 1 +} + +unset GIT_DIR GIT_WORK_TREE +cd "$worktree" && + +if grep -q "^diff --git " "$1" +then + validate_patch "$1" +else + validate_cover_letter "$1" +fi && + +if test "$GIT_SENDEMAIL_FILE_COUNTER" = "$GIT_SENDEMAIL_FILE_TOTAL" +then + git config --unset-all sendemail.validateWorktree && + trap 'git worktree remove -ff "$worktree"' EXIT && + validate_series +fi diff --git a/.github/shallow b/.github/shallow new file mode 100644 index 0000000..81f8ecd --- /dev/null +++ b/.github/shallow @@ -0,0 +1 @@ +01154b818dc4b2b96acd3e6804572db5d748564d diff --git a/.github/sun_checks.xml b/.github/sun_checks.xml new file mode 100644 index 0000000..a6f3b19 --- /dev/null +++ b/.github/sun_checks.xml @@ -0,0 +1,311 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.github/super-linter.env b/.github/super-linter.env new file mode 100644 index 0000000..acfefd9 --- /dev/null +++ b/.github/super-linter.env @@ -0,0 +1,101 @@ +# File will be loaded as environment variables +# It must contain strings like: +# name=value +# Commented VALIDATE_* means that the check is ON. + +VALIDATE_ANSIBLE=false +VALIDATE_ARM=false +# VALIDATE_BASH=false +VALIDATE_BASH_EXEC=false +VALIDATE_CPP=false +VALIDATE_CHECKOV=false +VALIDATE_CLANG_FORMAT=false +VALIDATE_CLOJURE=false +VALIDATE_CLOUDFORMATION=false +VALIDATE_COFFEESCRIPT=false +VALIDATE_CSHARP=false +VALIDATE_CSS=false +VALIDATE_CSS_PRETTIER=false +VALIDATE_DART=false +VALIDATE_DOCKERFILE_HADOLINT=false +VALIDATE_DOTNET_SLN_FORMAT_ANALYZERS=false +VALIDATE_DOTNET_SLN_FORMAT_STYLE=false +VALIDATE_DOTNET_SLN_FORMAT_WHITESPACE=false +VALIDATE_EDITORCONFIG=false +VALIDATE_ENV=false +VALIDATE_GIT_COMMITLINT=false +VALIDATE_GIT_MERGE_CONFLICT_MARKERS=false +# VALIDATE_GITHUB_ACTIONS=false +# VALIDATE_GITHUB_ACTIONS_ZIZMOR=false +VALIDATE_GITLEAKS=false +VALIDATE_GO=false +# VALIDATE_GO_MODULES=false +VALIDATE_GO_RELEASER=false +VALIDATE_GRAPHQL_PRETTIER=false +VALIDATE_GOOGLE_JAVA_FORMAT=false +VALIDATE_GROOVY=false +VALIDATE_HTML=false +VALIDATE_HTML_PRETTIER=false +# VALIDATE_JAVA=false +# VALIDATE_JAVASCRIPT_ES=false +VALIDATE_JAVASCRIPT_PRETTIER=false +VALIDATE_JSCPD=false +# VALIDATE_JSON=false +VALIDATE_JSON_PRETTIER=false +VALIDATE_JSONC=false +VALIDATE_JSONC_PRETTIER=false +VALIDATE_JSX=false +VALIDATE_JSX_PRETTIER=false +VALIDATE_JUPYTER_NBQA_BLACK=false +VALIDATE_JUPYTER_NBQA_FLAKE8=false +VALIDATE_JUPYTER_NBQA_ISORT=false +VALIDATE_JUPYTER_NBQA_MYPY=false +VALIDATE_JUPYTER_NBQA_PYLINT=false +VALIDATE_JUPYTER_NBQA_RUFF=false +VALIDATE_KOTLIN=false +VALIDATE_LATEX=false +VALIDATE_LUA=false +# VALIDATE_MARKDOWN=false +VALIDATE_MARKDOWN_PRETTIER=false +VALIDATE_NATURAL_LANGUAGE=false +VALIDATE_OPENAPI=false +VALIDATE_PERL=false +VALIDATE_PHP=false +VALIDATE_PHP_BUILTIN=false +VALIDATE_PHP_PHPCS=false +VALIDATE_PHP_PHPSTAN=false +VALIDATE_PHP_PSALM=false +VALIDATE_POWERSHELL=false +VALIDATE_PROTOBUF=false +# VALIDATE_PYTHON=false +VALIDATE_PYTHON_BLACK=false +VALIDATE_PYTHON_FLAKE8=false +VALIDATE_PYTHON_ISORT=false +VALIDATE_PYTHON_MYPY=false +VALIDATE_PYTHON_PYLINT=false +VALIDATE_PYTHON_RUFF=false +VALIDATE_R=false +VALIDATE_RENOVATE=false +VALIDATE_RUBY=false +VALIDATE_RUST_2015=false +VALIDATE_RUST_2018=false +VALIDATE_RUST_2021=false +VALIDATE_RUST_CLIPPY=false +VALIDATE_SCALAFMT=false +VALIDATE_SHELL_SHFMT=false +VALIDATE_SNAKEMAKE_LINT=false +VALIDATE_SNAKEMAKE_SNAKEFMT=false +VALIDATE_STATES=false +VALIDATE_SQLFLUFF=false +VALIDATE_TERRAFORM_FMT=false +VALIDATE_TERRAFORM_TERRASCAN=false +VALIDATE_TERRAFORM_TFLINT=false +VALIDATE_TERRAGRUNT=false +VALIDATE_TSX=false +# VALIDATE_TYPESCRIPT_ES=false +VALIDATE_TYPESCRIPT_PRETTIER=false +VALIDATE_VUE=false +VALIDATE_VUE_PRETTIER=false +# VALIDATE_XML=false +# VALIDATE_YAML=false +VALIDATE_YAML_PRETTIER=false diff --git a/.github/super-linter.md b/.github/super-linter.md new file mode 100644 index 0000000..1fa261b --- /dev/null +++ b/.github/super-linter.md @@ -0,0 +1,17 @@ +# Lint codebase (Super-linter) + +This workflow executes several linters on changed files based on languages used in your codebase whenever you push a code or open a pull request. +You can adjust the behavior by adding/modifying configuration files for super-linter itself and for individual linters. + +For more information, see: +[Super-linter](https://github.com/super-linter/super-linter) + +Configuration file for super-linter example: +[.github/super-linter.env](https://github.com/Netcracker/.github/blob/main/.github/super-linter.env) +Configuration files for individual linters should be placed in .github/linters + +**To add the super-linter workflow into your repository** just copy the [prepared file](https://github.com/Netcracker/.github/blob/main/workflow-templates/super-linter.yaml) into `.github/workflows` directory of your repository. + +> Super-linter workflow uses the centralized configuration from the [Netcracker/.github](https://github.com/Netcracker/.github/tree/main/config/linters) repository. +> One can override/add any linter configuration and super-linter environment by adding corresponding file into target repository. +> For example to override super-linter environment, just add `.github/super-linter.env` file to your repostory and set the env you need. The same for individual linter configuration. diff --git a/.github/super-linter.properties.json b/.github/super-linter.properties.json new file mode 100644 index 0000000..f3baa78 --- /dev/null +++ b/.github/super-linter.properties.json @@ -0,0 +1,8 @@ +{ + "name": "Qubership Lint Code Base", + "description": "Lint Code Base workflow template. It can be used to lint code base using super-linter.", + + "categories": [ + "Automation" + ] +} diff --git a/.github/super-linter.yaml b/.github/super-linter.yaml new file mode 100644 index 0000000..e8cbd24 --- /dev/null +++ b/.github/super-linter.yaml @@ -0,0 +1,85 @@ +--- +# This workflow executes several linters on changed files based on languages used in your code base whenever +# you push a code or open a pull request. +# +# You can adjust the behavior by modifying this file. +# For more information, see: +# https://github.com/super-linter/super-linter +# Configuration file for super-linter example: +# .github/super-linter.env +# Configuration files for individual linters should be placed in .github/linters + +name: Lint Code Base + +on: + push: + branches: + - '**' + pull_request: + branches: + - '**' + workflow_dispatch: + inputs: + full_scan: + type: boolean + default: false + required: false + description: "Lint all codebase" +permissions: + contents: read + +jobs: + super-linter: + runs-on: ubuntu-latest + permissions: + contents: read + packages: read + statuses: write + steps: + - name: "Get the common linters configuration" + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + ref: main # fix/superlinter-config + repository: netcracker/.github + persist-credentials: false + path: common-configs + sparse-checkout: | + config/linters + - name: "Move configs" + run: | + cp --update=none -vRT ./common-configs/config/linters /tmp/linters + rm -rf ./common-configs + # To report GitHub Actions status checks + - name: Checkout code + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + # Full git history is needed to get a proper list of changed files within `super-linter` + fetch-depth: 0 + persist-credentials: false + - name: "Apply the common linters configuration" + run: | + mkdir -p ./.github/linters + cp --update=none -vRT /tmp/linters ./.github/linters + + - name: "Load super-linter environment file" + shell: bash + run: | + # shellcheck disable=2086 + if [ -f "${GITHUB_WORKSPACE}/.github/super-linter.env" ]; then + echo "Applying local linter environment:" + grep "\S" ${GITHUB_WORKSPACE}/.github/super-linter.env | grep -v "^#" + grep "\S" ${GITHUB_WORKSPACE}/.github/super-linter.env | grep -v "^#" >> $GITHUB_ENV + elif [ -f "/tmp/linters/super-linter.env" ]; then + echo "::warning:: Local linter environment file .github/super-linter.env is not found" + echo "Applying common linter environment:" + grep "\S" /tmp/linters/super-linter.env | grep -v "^#" + grep "\S" /tmp/linters/super-linter.env | grep -v "^#" >> $GITHUB_ENV + fi + + - name: Lint Code Base + uses: super-linter/super-linter/slim@ffde3b2b33b745cb612d787f669ef9442b1339a6 # v8.1.0 + env: + VALIDATE_ALL_CODEBASE: ${{ inputs.full_scan || false }} + # To report GitHub Actions status checks + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DEFAULT_BRANCH: ${{ github.event.pull_request.base.ref || github.event.push.ref }} diff --git a/.github/topics.json b/.github/topics.json new file mode 100644 index 0000000..be91043 --- /dev/null +++ b/.github/topics.json @@ -0,0 +1,1726 @@ +[ + { + "repositoryName": ".github", + "repositoryTopics": [ + { + "name": "qubership-devops" + } + ] + }, + { + "repositoryName": "KubeMarine", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "base-images-module-base", + "repositoryTopics": [ + { + "name": "qubership-cm" + } + ] + }, + { + "repositoryName": "cassandra-exporter", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "cla-storage", + "repositoryTopics": [ + { + "name": "qubership-devops" + } + ] + }, + { + "repositoryName": "gatekeeper-library", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "get-package-ids", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "k8s-conformance", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "microservice-restclient", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "pg_hint_plan", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "pgskipper-backup-daemon", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "pgskipper-dbaas-adapter", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "pgskipper-monitoring-agent", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "pgskipper-operator", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "pgskipper-operator-core", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "pgskipper-patroni", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "pgskipper-pgbackrest-sidecar", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "pgskipper-replication-controller", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "pgskipper-upgrade", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "qubership-api-linter-service", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-agent", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-api-data-model", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-api-diff", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-api-doc-viewer", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-api-processor", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-api-unifier", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-api-visitor", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-apispec-view", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-backend", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-build-task-consumer", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-ci", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-class-view", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-compatibility-suites", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-graphapi", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-http-spec", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-jest-chrome-in-docker-environment", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-json-crawl", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-nodejs-dev-image", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-npm-gitflow", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-postman-collections", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-protobufjs-research", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-rest-playground", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-sniffer-agent", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-test-service", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-traffic-analyzer", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-ui", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-ui-tests", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-apihub-vscode", + "repositoryTopics": [ + { + "name": "qubership-apihub" + } + ] + }, + { + "repositoryName": "qubership-av-scan-service", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "qubership-backup-daemon", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "qubership-cloud-passport-cli", + "repositoryTopics": [ + { + "name": "qubership-cm" + } + ] + }, + { + "repositoryName": "qubership-colly", + "repositoryTopics": [ + { + "name": "qubership-devops" + } + ] + }, + { + "repositoryName": "qubership-consul", + "repositoryTopics": [ + { + "name": "qubership-devops" + } + ] + }, + { + "repositoryName": "qubership-consul-acl-configurator", + "repositoryTopics": [ + { + "name": "qubership-devops" + } + ] + }, + { + "repositoryName": "qubership-consul-backup-daemon", + "repositoryTopics": [ + { + "name": "qubership-devops" + } + ] + }, + { + "repositoryName": "qubership-core-arquillian-cube-extension", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-base-images", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-blue-green-state-monitor", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-blue-green-state-monitor-quarkus", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-commons", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-context-propagation", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-context-propagation-quarkus", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-control-plane", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-dbaas-agent", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-error-handling", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-infra", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-ingress-gateway", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-lib-go", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-lib-go-actuator-common", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-lib-go-bg-kafka", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-lib-go-bg-state-monitor", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-lib-go-dbaas-arangodb-client", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-lib-go-dbaas-base-client", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-lib-go-dbaas-cassandra-client", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-lib-go-dbaas-clickhouse-client", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-lib-go-dbaas-mongo-client", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-lib-go-dbaas-opensearch-client", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-lib-go-dbaas-postgres-client", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-lib-go-error-handling", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-lib-go-fiber-server-utils", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-lib-go-maas-bg-segmentio", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-lib-go-maas-client", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-lib-go-maas-core", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-lib-go-maas-segmentio", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-lib-go-mux-server-utils", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-lib-go-paas-mediation-client", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-lib-go-rest-utils", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-lib-go-stomp-websocket", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-maas-agent", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-microservice-dependencies", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-microservice-framework", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-microservice-framework-extensions", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-mongo-evolution", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-process-orchestrator", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-quarkus-extensions", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-rest-libraries", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-restclient", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-springboot-starter", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-core-utils", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-cql-driver", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "qubership-credential-manager", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "qubership-dbaas", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-dbaas-adapter-core", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-dbaas-client", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-deployment-status-provisioner", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "qubership-diag-proxy", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-disaster-recovery-daemon", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "qubership-docker-integration-tests", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "qubership-docker-opensearch", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "qubership-docker-zookeeper", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "qubership-env-checker", + "repositoryTopics": [ + { + "name": "qubership-devops" + } + ] + }, + { + "repositoryName": "qubership-envgene", + "repositoryTopics": [ + { + "name": "qubership-cm" + } + ] + }, + { + "repositoryName": "qubership-envgene-instance", + "repositoryTopics": [ + { + "name": "qubership-cm" + } + ] + }, + { + "repositoryName": "qubership-envgene-template", + "repositoryTopics": [ + { + "name": "qubership-cm" + } + ] + }, + { + "repositoryName": "qubership-external-logging-installer", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-fluent-pipeline-tests", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-fluentd", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-git-system-follower", + "repositoryTopics": [ + { + "name": "qubership-devops" + } + ] + }, + { + "repositoryName": "qubership-grafana-plugins-init", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-grafana-reporter", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-graphite-remote-adapter", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-graylog-archiving-plugin", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-graylog-auth-proxy", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-graylog-obfuscation-plugin", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-graylog-plugins-init", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-hive-metastore", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "qubership-integration-catalog-library", + "repositoryTopics": [ + { + "name": "qubership-integration" + } + ] + }, + { + "repositoryName": "qubership-integration-checkstyle", + "repositoryTopics": [ + { + "name": "qubership-integration" + } + ] + }, + { + "repositoryName": "qubership-integration-designtime-catalog", + "repositoryTopics": [ + { + "name": "qubership-integration" + } + ] + }, + { + "repositoryName": "qubership-integration-engine", + "repositoryTopics": [ + { + "name": "qubership-integration" + } + ] + }, + { + "repositoryName": "qubership-integration-platform", + "repositoryTopics": [ + { + "name": "qubership-integration" + } + ] + }, + { + "repositoryName": "qubership-integration-runtime-catalog", + "repositoryTopics": [ + { + "name": "qubership-integration" + } + ] + }, + { + "repositoryName": "qubership-integration-sessions-management", + "repositoryTopics": [ + { + "name": "qubership-integration" + } + ] + }, + { + "repositoryName": "qubership-integration-ui", + "repositoryTopics": [ + { + "name": "qubership-integration" + } + ] + }, + { + "repositoryName": "qubership-integration-variables-management", + "repositoryTopics": [ + { + "name": "qubership-integration" + } + ] + }, + { + "repositoryName": "qubership-inventory-tool-cli", + "repositoryTopics": [ + { + "name": "qubership-devops" + } + ] + }, + { + "repositoryName": "qubership-inventory-tool-core", + "repositoryTopics": [ + { + "name": "qubership-devops" + } + ] + }, + { + "repositoryName": "qubership-jaeger", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-kube-events-generator", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-kube-events-reader", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-landscape-config", + "repositoryTopics": [ + { + "name": "qubership-generic" + } + ] + }, + { + "repositoryName": "qubership-landscape-config-processor", + "repositoryTopics": [ + { + "name": "qubership-generic" + } + ] + }, + { + "repositoryName": "qubership-hub-test", + "repositoryTopics": [ + { + "name": "qubership-devops" + } + ] + }, + { + "repositoryName": "qubership-log-exporter", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-log-generator", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-logging-operator", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-maas", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-maas-client", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-maas-client-quarkus", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-maas-client-spring", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-maas-declarative-client-commons", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-maas-declarative-client-quarkus", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-maas-declarative-client-spring", + "repositoryTopics": [ + { + "name": "qubership-core" + } + ] + }, + { + "repositoryName": "qubership-mistral", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "qubership-mongodb-driver", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "qubership-monitoring-operator", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-network-latency-exporter", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-nifi", + "repositoryTopics": [ + { + "name": "qubership-nifi" + } + ] + }, + { + "repositoryName": "qubership-nifi-registry", + "repositoryTopics": [ + { + "name": "qubership-nifi" + } + ] + }, + { + "repositoryName": "qubership-nosqldb-operator-core", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "qubership-observability-examples", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-observability-operator", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-open-telemetry-collector", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-opensearch", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "qubership-opensearch-curator", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "qubership-opensearch-dbaas-adapter", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "qubership-opensearch-monitoring", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "qubership-opentelemetry-helm-charts", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-pipelines-common-python-library", + "repositoryTopics": [ + { + "name": "qubership-devops" + } + ] + }, + { + "repositoryName": "qubership-profiler-agent", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-prometheus-adapter-operator", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-query-exporter", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "qubership-renovate-config", + "repositoryTopics": [ + { + "name": "qubership-devops" + } + ] + }, + { + "repositoryName": "qubership-repo-template", + "repositoryTopics": [ + { + "name": "qubership-devops" + } + ] + }, + { + "repositoryName": "qubership-tcp-duplicator", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-test-pipelines", + "repositoryTopics": [ + { + "name": "qubership-devops" + } + ] + }, + { + "repositoryName": "qubership-version-exporter", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-workflow-hub", + "repositoryTopics": [ + { + "name": "qubership-devops" + } + ] + }, + { + "repositoryName": "qubership-zookeeper", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "qubership-zookeeper-backup-daemon", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "qubership-zookeeper-monitoring", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "robot-shop", + "repositoryTopics": [ + { + "name": "qubership-observability" + } + ] + }, + { + "repositoryName": "qubership-testing-platform-auth-library", + "repositoryTopics": [ + { + "name": "qubership-tp" + } + ] + }, + { + "repositoryName": "qubership-testing-platform-codecheck-library", + "repositoryTopics": [ + { + "name": "qubership-tp" + } + ] + }, + { + "repositoryName": "qubership-testing-platform-common-auditing-library", + "repositoryTopics": [ + { + "name": "qubership-tp" + } + ] + }, + { + "repositoryName": "qubership-testing-platform-common-library", + "repositoryTopics": [ + { + "name": "qubership-tp" + } + ] + }, + { + "repositoryName": "qubership-testing-platform-configuration-dataset-excel-library", + "repositoryTopics": [ + { + "name": "qubership-tp" + } + ] + }, + { + "repositoryName": "qubership-testing-platform-crypt-library", + "repositoryTopics": [ + { + "name": "qubership-tp" + } + ] + }, + { + "repositoryName": "qubership-testing-platform-diameter-transport-library", + "repositoryTopics": [ + { + "name": "qubership-tp" + } + ] + }, + { + "repositoryName": "qubership-testing-platform-export-import-library", + "repositoryTopics": [ + { + "name": "qubership-tp" + } + ] + }, + { + "repositoryName": "qubership-testing-platform-integration-library", + "repositoryTopics": [ + { + "name": "qubership-tp" + } + ] + }, + { + "repositoryName": "qubership-testing-platform-itf-core-library", + "repositoryTopics": [ + { + "name": "qubership-tp" + } + ] + }, + { + "repositoryName": "qubership-testing-platform-macros-core-library", + "repositoryTopics": [ + { + "name": "qubership-tp" + } + ] + }, + { + "repositoryName": "qubership-testing-platform-multitenancy-library", + "repositoryTopics": [ + { + "name": "qubership-tp" + } + ] + }, + { + "repositoryName": "qubership-testing-platform-ss7-transport-library", + "repositoryTopics": [ + { + "name": "qubership-tp" + } + ] + }, + { + "repositoryName": "qubership-testing-platform-datasets", + "repositoryTopics": [ + { + "name": "qubership-tp" + } + ] + }, + { + "repositoryName": "qubership-testing-platform-environments", + "repositoryTopics": [ + { + "name": "qubership-tp" + } + ] + }, + { + "repositoryName": "qubership-testing-platform-itf-executor", + "repositoryTopics": [ + { + "name": "qubership-tp" + } + ] + }, + { + "repositoryName": "qubership-testing-platform-itf-reporting", + "repositoryTopics": [ + { + "name": "qubership-tp" + } + ] + }, + { + "repositoryName": "qubership-testing-platform-itf-stubs", + "repositoryTopics": [ + { + "name": "qubership-tp" + } + ] + }, + { + "repositoryName": "qubership-testing-platform-itf-lite-backend", + "repositoryTopics": [ + { + "name": "qubership-tp" + } + ] + }, + { + "repositoryName": "qubership-testing-platform-ram", + "repositoryTopics": [ + { + "name": "qubership-tp" + } + ] + }, + { + "repositoryName": "chart-releaser-action", + "repositoryTopics": [ + { + "name": "qubership-devops" + } + ] + }, + { + "repositoryName": "qubership-integration-schemas", + "repositoryTopics": [ + { + "name": "qubership-integration" + } + ] + }, + { + "repositoryName": "release-drafter", + "repositoryTopics": [ + { + "name": "qubership-devops" + } + ] + }, + { + "repositoryName": "arangodb-patches", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "cassandra-patches", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "consul-patches", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "kafka-patches", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "keycloak-patches", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "postgres-patches", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "qubership-backup-daemon-go", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "rabbitmq-patches", + "repositoryTopics": [ + { + "name": "qubership-infra" + } + ] + }, + { + "repositoryName": "qubership-integration-vscode-extension", + "repositoryTopics": [ + { + "name": "qip" + }, + { + "name": "qubership-integration" + } + ] + } + + ] diff --git a/.github/topics.yaml b/.github/topics.yaml new file mode 100644 index 0000000..3c5ee08 --- /dev/null +++ b/.github/topics.yaml @@ -0,0 +1,118 @@ +name: Update Repository Topics + +on: + workflow_dispatch: + inputs: + org_name: + description: "Name of GitHub organization (leave empty to use default)" + required: true + default: "Netcracker" + repo_names: + description: "Specific repository to update (leave empty to update all)" + required: false + default: "" + replace: + description: "Replace existing topics (leave empty to add topics)" + type: boolean + required: false + default: false + +permissions: + contents: read + +jobs: + update-topics: + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 + with: + persist-credentials: false + + - name: Validate and Update Topics + run: | + set -euo pipefail + JSON_FILE="./config/topics.json" + + if [ ! -f "$JSON_FILE" ]; then + echo "::error ::topics.json file not found!" + exit 1 + fi + + # Validate repositoryName fields + INVALID_ENTRIES=$(jq -r '.[] | select(.repositoryName | contains(",")) | .repositoryName' "$JSON_FILE") + if [ -n "$INVALID_ENTRIES" ]; then + echo "::error ::Invalid repositoryName entries detected:" + echo "$INVALID_ENTRIES" + exit 1 + else + echo "All repositoryName fields are valid." + fi + + # Check if a specific repository is provided + if [ -n "$REPO_NAMES" ]; then + echo "Run for repositories: $REPO_NAMES" + + IFS=',' read -ra REPOS <<< "$REPO_NAMES" + + for REPO_NAME in "${REPOS[@]}"; do + REPO_NAME=$(echo "$REPO_NAME" | xargs) # trim пробелы + + REPO_ENTRY=$(jq -c '.[] | select(.repositoryName=="'"$REPO_NAME"'")' "$JSON_FILE") + if [ -z "$REPO_ENTRY" ]; then + echo "::warning ::Repository $REPO_NAME not found in topics.json. Skipping." + continue + fi + + TOPICS=$(echo "$REPO_ENTRY" | jq -r '.repositoryTopics[].name' | paste -sd "," -) + + if [ -z "$TOPICS" ]; then + echo "::warning ::No topics found for $REPO_NAME. Skipping." + continue + fi + + echo "Updating topics for $REPO_NAME: $TOPICS" + + if [ "$REPLACE" = "true" ]; then + CURRENT=$(gh api repos/$GH_ORG/$REPO_NAME/topics -q '.names[]') + for t in $CURRENT; do + gh repo edit "$GH_ORG/$REPO_NAME" --remove-topic "$t" || \ + echo "::warning ::Error removing topic $t from $REPO_NAME" + done + fi + + gh repo edit "$GH_ORG/$REPO_NAME" --add-topic "$TOPICS" || \ + echo "::warning ::Error updating $REPO_NAME. Skipping." + done + else + # Process all repositories + jq -c '.[]' "$JSON_FILE" | while read -r repo; do + REPO_NAME=$(echo "$repo" | jq -r '.repositoryName') + TOPICS=$(echo "$repo" | jq -r '.repositoryTopics[].name' | paste -sd "," -) + + if [ -z "$TOPICS" ]; then + echo "No topics found for $REPO_NAME. Skipping." + continue + fi + + echo "Updating topics for $REPO_NAME: $TOPICS" + + if [ "$REPLACE" = "true" ]; then + echo "Replacing topics for $REPO_NAME" + CURRENT=$(gh api repos/$GH_ORG/$REPO_NAME/topics -q '.names[]') + for t in $CURRENT; do + gh repo edit "$GH_ORG/$REPO_NAME" --remove-topic "$t" || \ + echo "::warning ::Error removing topic $t from $REPO_NAME" + done + fi + + gh repo edit "$GH_ORG/$REPO_NAME" --add-topic "$TOPICS" || \ + echo "::warning ::Error updating $REPO_NAME. Skipping." + done + fi + env: + GITHUB_TOKEN: ${{ secrets.GH_ACCESS_TOKEN }} + GH_ORG: ${{ github.event.inputs.org_name }} + REPO_NAMES: ${{ github.event.inputs.repo_names }} + REPLACE: ${{ github.event.inputs.replace }} diff --git a/.github/update.sample b/.github/update.sample new file mode 100755 index 0000000..c4d426b --- /dev/null +++ b/.github/update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to block unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 )" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --type=bool hooks.allowunannotated) +allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch) +denycreatebranch=$(git config --type=bool hooks.denycreatebranch) +allowdeletetag=$(git config --type=bool hooks.allowdeletetag) +allowmodifytag=$(git config --type=bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero=$(git hash-object --stdin &2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/.github/zizmor.yaml b/.github/zizmor.yaml new file mode 100644 index 0000000..bda7fc6 --- /dev/null +++ b/.github/zizmor.yaml @@ -0,0 +1,5 @@ +rules: + dangerous-triggers: + ignore: + - cla.yaml + - pr-assigner.yml