diff --git a/.github/workflows/automatic-pr-labeler.yaml b/.github/workflows/automatic-pr-labeler.yaml new file mode 100644 index 0000000000..c4c5b8927a --- /dev/null +++ b/.github/workflows/automatic-pr-labeler.yaml @@ -0,0 +1,58 @@ +--- + +# 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 +run-name: PR #${{ github.event.pull_request.number }} - Automatic Labeler +on: + pull_request: + branches: [main] + types: + [opened, reopened, synchronize] + +permissions: + contents: read + +jobs: + assign-labels: + name: "Assign Labels to PR #${{ github.event.pull_request.number }}" + 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: + - name: "Checkout Repository" + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + 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 for PR from fork" + 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/workflows/link-checker.yaml b/.github/workflows/link-checker.yaml new file mode 100644 index 0000000000..478675a136 --- /dev/null +++ b/.github/workflows/link-checker.yaml @@ -0,0 +1,49 @@ +--- +name: "Link Checker" + +on: + push: null + repository_dispatch: null + workflow_dispatch: null + pull_request: + branches: [main] +permissions: + contents: read +jobs: + linkChecker: + name: "Run Link Checker" + runs-on: ubuntu-latest + steps: + - name: "Checkout code" + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + with: + persist-credentials: false + + - name: "Restore lychee cache" + uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 + id: restore-cache + with: + path: .lycheecache + key: cache-lychee-${{ github.sha }} + restore-keys: cache-lychee- + + - name: "Link Checker" + id: lychee + uses: lycheeverse/lychee-action@8646ba30535128ac92d33dfc9133794bfdd9b411 #v2.8.0 + 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/workflows/pr-assigner.yml b/.github/workflows/pr-assigner.yml new file mode 100644 index 0000000000..b89f271b5c --- /dev/null +++ b/.github/workflows/pr-assigner.yml @@ -0,0 +1,35 @@ +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: + contents: read + +jobs: + pr-auto-assign: + name: "Auto-assign Reviewers to PR #${{ github.event.pull_request.number }}" + runs-on: ubuntu-latest + permissions: + pull-requests: write + contents: read + 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 + + - name: "Checkout Repository" + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 + with: + persist-credentials: false + + - name: "Assign Reviewers" + uses: netcracker/qubership-workflow-hub/actions/pr-assigner@5a557213e92e3d22d0292330c4817c82af6704d2 #2.1.2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/pr-lint-title.yaml b/.github/workflows/pr-lint-title.yaml new file mode 100644 index 0000000000..f3aeb74484 --- /dev/null +++ b/.github/workflows/pr-lint-title.yaml @@ -0,0 +1,24 @@ +--- + +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: + - name: "Semantic PR Title Lint" + uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1 + env: + GITHUB_TOKEN: ${{ github.token }} diff --git a/.github/workflows/profanity-filter.yaml b/.github/workflows/profanity-filter.yaml new file mode 100644 index 0000000000..194f846bc6 --- /dev/null +++ b/.github/workflows/profanity-filter.yaml @@ -0,0 +1,30 @@ +--- +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: + name: "Apply Profanity 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@7d6e0c79ee3d33ae09b5ed0c6e2fa04b9c512e08 #10.0 + 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/workflows/super-linter.yaml b/.github/workflows/super-linter.yaml new file mode 100644 index 0000000000..8d3278c234 --- /dev/null +++ b/.github/workflows/super-linter.yaml @@ -0,0 +1,86 @@ +--- +# 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: + name: "Lint Code Base" + runs-on: ubuntu-latest + permissions: + contents: read + packages: read + statuses: write + steps: + - name: "Get the common linters configuration" + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + 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@61abc07d755095a68f4987d1c2c3d1d64408f1f9 # v8.5.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 }}