From 7db046b48b92d6e24ec15193677b99cea46d7077 Mon Sep 17 00:00:00 2001 From: LizardByte-bot <108553330+LizardByte-bot@users.noreply.github.com> Date: Thu, 5 Oct 2023 18:40:31 +0000 Subject: [PATCH] ci: update global workflows --- .github/dependabot.yml | 48 +++++ .github/label-actions.yml | 49 +++++ .github/pr_release_template.md | 28 +++ .github/workflows/auto-create-pr.yml | 35 ++++ .github/workflows/automerge.yml | 64 ++++++ .github/workflows/ci-qodana.yml | 292 +++++++++++++++++++++++++++ .github/workflows/codeql.yml | 137 +++++++++++++ .github/workflows/dispatcher.yml | 69 +++++++ .github/workflows/issues-stale.yml | 61 ++++++ .github/workflows/issues.yml | 25 +++ .github/workflows/yaml-lint.yml | 66 ++++++ 11 files changed, 874 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/label-actions.yml create mode 100644 .github/pr_release_template.md create mode 100644 .github/workflows/auto-create-pr.yml create mode 100644 .github/workflows/automerge.yml create mode 100644 .github/workflows/ci-qodana.yml create mode 100644 .github/workflows/codeql.yml create mode 100644 .github/workflows/dispatcher.yml create mode 100644 .github/workflows/issues-stale.yml create mode 100644 .github/workflows/issues.yml create mode 100644 .github/workflows/yaml-lint.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..6eb0cda --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,48 @@ +--- +# This action is centrally managed in https://github.com//.github/ +# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in +# the above-mentioned repo. + +version: 2 +updates: + - package-ecosystem: "docker" + directory: "/" + schedule: + interval: "daily" + time: "08:00" + open-pull-requests-limit: 10 + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + time: "08:30" + open-pull-requests-limit: 10 + + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "daily" + time: "09:00" + open-pull-requests-limit: 10 + + - package-ecosystem: "nuget" + directory: "/" + schedule: + interval: "daily" + time: "09:30" + open-pull-requests-limit: 10 + + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "daily" + time: "10:00" + open-pull-requests-limit: 10 + + - package-ecosystem: "gitsubmodule" + directory: "/" + schedule: + interval: "daily" + time: "10:30" + open-pull-requests-limit: 10 diff --git a/.github/label-actions.yml b/.github/label-actions.yml new file mode 100644 index 0000000..2949601 --- /dev/null +++ b/.github/label-actions.yml @@ -0,0 +1,49 @@ +--- +# This action is centrally managed in https://github.com//.github/ +# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in +# the above-mentioned repo. + +# Configuration for Label Actions - https://github.com/dessant/label-actions + +added: + comment: > + This feature has been added and will be available in the next release. +fixed: + comment: > + This issue has been fixed and will be available in the next release. +invalid:duplicate: + comment: > + :wave: @{issue-author}, this appears to be a duplicate of a pre-existing issue. + close: true + lock: true + unlabel: 'status:awaiting-triage' + +-invalid:duplicate: + reopen: true + unlock: true + +invalid:support: + comment: > + :wave: @{issue-author}, we use the issue tracker exclusively for bug reports. + However, this issue appears to be a support request. Please use our + [Support Center](https://app.lizardbyte.dev/support) for support issues. Thanks. + close: true + lock: true + lock-reason: 'off-topic' + unlabel: 'status:awaiting-triage' + +-invalid:support: + reopen: true + unlock: true + +invalid:template-incomplete: + issues: + comment: > + :wave: @{issue-author}, please edit your issue to complete the template with + all the required info. Your issue will be automatically closed in 5 days if + the template is not completed. Thanks. + prs: + comment: > + :wave: @{issue-author}, please edit your PR to complete the template with + all the required info. Your PR will be automatically closed in 5 days if + the template is not completed. Thanks. diff --git a/.github/pr_release_template.md b/.github/pr_release_template.md new file mode 100644 index 0000000..b6f6acf --- /dev/null +++ b/.github/pr_release_template.md @@ -0,0 +1,28 @@ +## Description + +This PR was created automatically. + + +### Screenshot + + + +### Issues Fixed or Closed + + + + + +## Type of Change +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] Dependency update (updates to dependencies) +- [ ] Documentation update (changes to documentation) +- [ ] Repository update (changes to repository files, e.g. `.github/...`) + +## Branch Updates +- [x] I want maintainers to keep my branch updated + +## Changelog Summary + diff --git a/.github/workflows/auto-create-pr.yml b/.github/workflows/auto-create-pr.yml new file mode 100644 index 0000000..13705dd --- /dev/null +++ b/.github/workflows/auto-create-pr.yml @@ -0,0 +1,35 @@ +--- +# This action is centrally managed in https://github.com//.github/ +# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in +# the above-mentioned repo. + +# This workflow creates a PR automatically when anything is merged/pushed into the `nightly` branch. The PR is created +# against the `master` (default) branch. + +name: Auto create PR + +on: + push: + branches: + - 'nightly' + +jobs: + create_pr: + if: startsWith(github.repository, 'LizardByte/') + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Create Pull Request + uses: repo-sync/pull-request@v2 + with: + source_branch: "" # should be "nightly" as it's the triggering branch + destination_branch: "master" + pr_title: "Pulling ${{ github.ref_name }} into master" + pr_template: ".github/pr_release_template.md" + pr_assignee: "${{ secrets.GH_BOT_NAME }}" + pr_draft: true + pr_allow_empty: false + github_token: ${{ secrets.GH_BOT_TOKEN }} diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml new file mode 100644 index 0000000..49ddebf --- /dev/null +++ b/.github/workflows/automerge.yml @@ -0,0 +1,64 @@ +--- +# This action is centrally managed in https://github.com//.github/ +# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in +# the above-mentioned repo. + +# This workflow will, first, automatically approve PRs created by @LizardByte-bot. Then it will automerge relevant PRs. + +name: Automerge PR + +on: + pull_request: + types: + - opened + - synchronize + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + autoapprove: + if: >- + contains(fromJson('["LizardByte-bot"]'), github.event.pull_request.user.login) && + contains(fromJson('["LizardByte-bot"]'), github.actor) && + startsWith(github.repository, 'LizardByte/') + runs-on: ubuntu-latest + steps: + - name: Autoapproving + uses: hmarr/auto-approve-action@v3 + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + + - name: Label autoapproved + uses: actions/github-script@v6 + with: + github-token: ${{ secrets.GH_BOT_TOKEN }} + script: | + github.rest.issues.addLabels({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + labels: ['autoapproved', 'autoupdate'] + }) + + automerge: + if: startsWith(github.repository, 'LizardByte/') + needs: [autoapprove] + runs-on: ubuntu-latest + + steps: + - name: Automerging + uses: pascalgn/automerge-action@v0.15.6 + env: + BASE_BRANCHES: nightly + GITHUB_TOKEN: ${{ secrets.GH_BOT_TOKEN }} + GITHUB_LOGIN: ${{ secrets.GH_BOT_NAME }} + MERGE_LABELS: "!dependencies" + MERGE_METHOD: "squash" + MERGE_COMMIT_MESSAGE: "{pullRequest.title} (#{pullRequest.number})" + MERGE_DELETE_BRANCH: true + MERGE_ERROR_FAIL: true + MERGE_FILTER_AUTHOR: ${{ secrets.GH_BOT_NAME }} + MERGE_RETRIES: "240" # 1 hour + MERGE_RETRY_SLEEP: "15000" # 15 seconds diff --git a/.github/workflows/ci-qodana.yml b/.github/workflows/ci-qodana.yml new file mode 100644 index 0000000..efc5634 --- /dev/null +++ b/.github/workflows/ci-qodana.yml @@ -0,0 +1,292 @@ +--- +# This action is centrally managed in https://github.com//.github/ +# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in +# the above-mentioned repo. + +name: Qodana + +on: + pull_request: + branches: [master, nightly] + types: [opened, synchronize, reopened] + push: + branches: [master, nightly] + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + qodana_initial_check: + name: Qodana Initial Check + permissions: + actions: write # required to use workflow dispatch on fork PRs + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Prepare + id: prepare + run: | + # check the branch variable + if [ "${{ github.event_name }}" == "push" ] + then + echo "This is a PUSH event" + # use the branch name + destination=${{ github.ref_name }} + target=${{ github.ref_name }} + else + echo "This is a PR event" + # use the PR number + destination=${{ github.event.pull_request.number }} + target=${{ github.event.pull_request.base.ref }} + fi + + echo "checkout_repo=$checkout_repo" >> $GITHUB_OUTPUT + echo "checkout_ref=$checkout_ref" >> $GITHUB_OUTPUT + echo "destination=$destination" >> $GITHUB_OUTPUT + echo "target=$target" >> $GITHUB_OUTPUT + + # prepare urls + base=https://${{ github.repository_owner }}.github.io + report_url=${base}/qodana-reports/${{ github.event.repository.name }}/${destination} + echo "report_url=$report_url" >> $GITHUB_OUTPUT + + # build matrix + files=$(find . -type f -iname "qodana*.yaml") + + echo "files: ${files}" + + # do not quote to keep this as a single line + echo files=${files} >> $GITHUB_OUTPUT + + MATRIX_COMBINATIONS="" + REPORTS_MARKDOWN="" + for FILE in ${files}; do + # extract the language from file name after `qodana-` and before `.yaml` + language=$(echo $FILE | sed -r -z -e 's/(\.\/)*.*\/(qodana.yaml)/default/gm') + if [[ $language != "default" ]]; then + language=$(echo $FILE | sed -r -z -e 's/(\.\/)*.*qodana-(.*).yaml/\2/gm') + fi + MATRIX_COMBINATIONS="$MATRIX_COMBINATIONS {\"file\": \"$FILE\", \"language\": \"$language\"}," + REPORTS_MARKDOWN="$REPORTS_MARKDOWN
- [${language}](${report_url}/${language})" + done + + # removes the last character (i.e. comma) + MATRIX_COMBINATIONS=${MATRIX_COMBINATIONS::-1} + + # setup matrix for later jobs + matrix=$(( + echo "{ \"include\": [$MATRIX_COMBINATIONS] }" + ) | jq -c .) + + echo $matrix + echo $matrix | jq . + echo "matrix=$matrix" >> $GITHUB_OUTPUT + + echo "reports_markdown=$REPORTS_MARKDOWN" >> $GITHUB_OUTPUT + + - name: Setup initial notification inputs + id: inputs + if: >- + startsWith(github.event_name, 'pull_request') && + steps.prepare.outputs.files != '' + run: | + # workflow logs + workflow_url_a=https://github.com/${{ github.repository_owner }}/${{ github.event.repository.name }} + workflow_url=${workflow_url_a}/actions/runs/${{ github.run_id }} + + # multiline message + message=$(cat <<- EOF + :warning: **Qodana is checking this PR** :warning: + Live results available [here](${workflow_url}) + EOF + ) + + # escape json control characters + message=$(jq -n --arg message "$message" '$message' | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g') + + secondary_inputs=$(echo '{ + "issue_message": "'"${message}"'", + "issue_message_id": "'"qodana"'", + "issue_number": "'"${{ github.event.number }}"'", + "issue_repo_owner": "'"${{ github.repository_owner }}"'", + "issue_repo_name": "'"${{ github.event.repository.name }}"'" + }' | jq -r .) + + #escape json control characters + secondary_inputs=$(jq -n --arg secondary_inputs "$secondary_inputs" '$secondary_inputs' \ + | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g') + + echo $secondary_inputs + + # secondary input as string, not JSON + # todo - change dispatch_ref to master instead of nightly + primary_inputs=$(echo '{ + "dispatch_repository": "'"${{ github.repository_owner }}/.github"'", + "dispatch_workflow": "'"dispatch-issue-comment.yml"'", + "dispatch_ref": "'"nightly"'", + "dispatch_inputs": "'"${secondary_inputs}"'" + }' | jq -c .) + + echo $primary_inputs + echo $primary_inputs | jq . + echo "primary_inputs=$primary_inputs" >> $GITHUB_OUTPUT + + - name: Workflow Dispatch + if: >- + startsWith(github.event_name, 'pull_request') && + steps.prepare.outputs.files != '' + uses: benc-uk/workflow-dispatch@v1.2.2 + continue-on-error: true # this might error if the workflow is not found, but we still want to run the next job + with: + ref: ${{ github.base_ref || github.ref_name }} # base ref for PR and branch name for push + workflow: dispatcher.yml + inputs: ${{ steps.inputs.outputs.primary_inputs }} + token: ${{ github.token }} + + outputs: + destination: ${{ steps.prepare.outputs.destination }} + target: ${{ steps.prepare.outputs.target }} + files: ${{ steps.prepare.outputs.files }} + reports_markdown: ${{ steps.prepare.outputs.reports_markdown }} + matrix: ${{ steps.prepare.outputs.matrix }} + + qodana: + if: ${{ needs.qodana_initial_check.outputs.files != '' }} + needs: [qodana_initial_check] + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.qodana_initial_check.outputs.matrix) }} + name: Qodana-Scan-${{ matrix.language }} + continue-on-error: true + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Get baseline + id: baseline + run: | + # check if destination is not an integer + if ! [[ "${{ needs.qodana_initial_check.outputs.destination }}" =~ ^[0-9]+$ ]] + then + echo "Running for a branch update" + echo "baseline_args=" >> $GITHUB_OUTPUT + else + echo "Running for a PR" + + sarif_file=qodana.sarif.json + repo=${{ github.event.repository.name }} + target=${{ needs.qodana_initial_check.outputs.target }} + language=${{ matrix.language }} + + baseline_file="${repo}/${target}/${language}/results/${sarif_file}" + baseline_file_url="https://lizardbyte.github.io/qodana-reports/${baseline_file}" + + # don't fail if file does not exist + wget ${baseline_file_url} || true + + # check if file exists + if [ -f ${sarif_file} ] + then + echo "baseline exists" + echo "baseline_args=--baseline,${sarif_file}" >> $GITHUB_OUTPUT + else + echo "baseline does not exist" + echo "baseline_args=" >> $GITHUB_OUTPUT + fi + fi + + - name: Rename Qodana config file + id: rename + run: | + # rename the file + if [ "${{ matrix.file }}" != "./qodana.yaml" ] + then + mv -f ${{ matrix.file }} ./qodana.yaml + fi + + - name: Qodana + id: qodana + continue-on-error: true # ensure dispatch-qodana job is run + uses: JetBrains/qodana-action@v2023.2.6 + with: + additional-cache-hash: ${{ github.ref }}-${{ matrix.language }} + artifact-name: qodana-${{ matrix.language }} # yamllint disable-line rule:line-length + args: '--print-problems,${{ steps.baseline.outputs.baseline_args }}' + pr-mode: false + upload-result: true + use-caches: true + + - name: Set output status + id: status + run: | + # check if qodana failed + echo "qodana_status=${{ steps.qodana.outcome }}" >> $GITHUB_OUTPUT + + outputs: + qodana_status: ${{ steps.status.outputs.qodana_status }} + + dispatch-qodana: + # trigger qodana-reports to download artifacts from the matrix runs + needs: [qodana_initial_check, qodana] + runs-on: ubuntu-latest + name: Dispatch Qodana + permissions: + actions: write # required to use workflow dispatch on fork PRs + if: ${{ needs.qodana_initial_check.outputs.files != '' }} + steps: + - name: Setup qodana publish inputs + id: inputs + run: | + # get the artifacts + artifacts=${{ toJson(steps.artifacts.outputs.result) }} + artifacts=$(echo $artifacts | jq -c .) + + # get the target branch + target=${{ needs.qodana_initial_check.outputs.target }} + + # get the destination branch + destination=${{ needs.qodana_initial_check.outputs.destination }} + + # client payload + secondary_inputs=$(echo '{ + "destination": "'"${destination}"'", + "ref": "'"${{ github.ref }}"'", + "repo": "'"${{ github.repository }}"'", + "repo_name": "'"${{ github.event.repository.name }}"'", + "run_id": "'"${{ github.run_id }}"'", + "reports_markdown": "'"${{ needs.qodana_initial_check.outputs.reports_markdown }}"'", + "status": "'"${{ needs.qodana.outputs.qodana_status }}"'" + }' | jq -r .) + + #escape json control characters + secondary_inputs=$(jq -n --arg secondary_inputs "$secondary_inputs" '$secondary_inputs' \ + | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g') + + echo $secondary_inputs + + primary_inputs=$(echo '{ + "dispatch_repository": "'"${{ github.repository_owner }}/qodana-reports"'", + "dispatch_workflow": "'"dispatch-qodana.yml"'", + "dispatch_ref": "'"master"'", + "dispatch_inputs": "'"$secondary_inputs"'" + }' | jq -c .) + + echo $primary_inputs + echo $primary_inputs | jq . + echo "primary_inputs=$primary_inputs" >> $GITHUB_OUTPUT + + - name: Workflow Dispatch + uses: benc-uk/workflow-dispatch@v1.2.2 + continue-on-error: true # this might error if the workflow is not found, but we don't want to fail the workflow + with: + ref: ${{ github.base_ref || github.ref_name }} # base ref for PR and branch name for push + workflow: dispatcher.yml + inputs: ${{ steps.inputs.outputs.primary_inputs }} + token: ${{ github.token }} diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..bedd996 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,137 @@ +--- +# This action is centrally managed in https://github.com//.github/ +# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in +# the above-mentioned repo. + +# This workflow will analyze all supported languages in the repository using CodeQL Analysis. + +name: "CodeQL" + +on: + push: + branches: ["master", "nightly"] + pull_request: + branches: ["master", "nightly"] + schedule: + - cron: '00 12 * * 0' # every Sunday at 12:00 UTC + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + languages: + name: Get language matrix + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.lang.outputs.result }} + continue: ${{ steps.continue.outputs.result }} + steps: + - name: Get repo languages + uses: actions/github-script@v6 + id: lang + with: + script: | + // CodeQL supports ['cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby', 'swift'] + // Use only 'java' to analyze code written in Java, Kotlin or both + // Use only 'javascript' to analyze code written in JavaScript, TypeScript or both + // Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + const supported_languages = ['cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby', 'swift'] + + const remap_languages = { + 'c++': 'cpp', + 'c#': 'csharp', + 'kotlin': 'java', + 'typescript': 'javascript', + } + + const repo = context.repo + const response = await github.rest.repos.listLanguages(repo) + let matrix = { + "include": [] + } + + for (let [key, value] of Object.entries(response.data)) { + // remap language + if (remap_languages[key.toLowerCase()]) { + console.log(`Remapping language: ${key} to ${remap_languages[key.toLowerCase()]}`) + key = remap_languages[key.toLowerCase()] + } + if (supported_languages.includes(key.toLowerCase()) && + !matrix['include'].includes({"language": key.toLowerCase()})) { + console.log(`Found supported language: ${key}`) + matrix['include'].push({"language": key.toLowerCase()}) + } + } + + // print languages + console.log(`matrix: ${JSON.stringify(matrix)}`) + + return matrix + + - name: Continue + uses: actions/github-script@v6 + id: continue + with: + script: | + // if matrix['include'] is an empty list return false, otherwise true + const matrix = ${{ steps.lang.outputs.result }} // this is already json encoded + + if (matrix['include'].length == 0) { + return false + } else { + return true + } + + analyze: + name: Analyze + if: ${{ needs.languages.outputs.continue == 'true' }} + needs: [languages] + runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} + timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.languages.outputs.matrix) }} + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # yamllint disable-line rule:line-length + # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + # Pre autobuild + # create a file named .codeql-prebuild-${{ matrix.language }}.sh in the root of your repository + - name: Prebuild + run: | + # check if .qodeql-prebuild-${{ matrix.language }}.sh exists + if [ -f "./.codeql-prebuild-${{ matrix.language }}.sh" ]; then + echo "Running .codeql-prebuild-${{ matrix.language }}.sh" + ./.codeql-prebuild-${{ matrix.language }}.sh + fi + + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/dispatcher.yml b/.github/workflows/dispatcher.yml new file mode 100644 index 0000000..c83a233 --- /dev/null +++ b/.github/workflows/dispatcher.yml @@ -0,0 +1,69 @@ +--- +# This action is centrally managed in https://github.com//.github/ +# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in +# the above-mentioned repo. + +# This action receives a dispatch event and passes it through to another repo. This is a workaround to avoid issues +# where fork PRs do not have access to secrets. + +name: Dispatcher + +on: + workflow_dispatch: + inputs: + dispatch_repository: + description: 'Repository to dispatch to' + required: true + dispatch_workflow: + description: 'Workflow to dispatch to' + required: true + dispatch_ref: + description: 'Ref/branch to dispatch to' + required: true + dispatch_inputs: + description: 'Inputs to send' + required: true + +jobs: + dispatcher: + name: Repository Dispatch + runs-on: ubuntu-latest + steps: + - name: Unescape JSON control characters + id: inputs + run: | + # get the inputs + dispatch_inputs=${{ github.event.inputs.dispatch_inputs }} + echo "$dispatch_inputs" + + # temporarily replace newlines with a placeholder + dispatch_inputs=$(echo ${dispatch_inputs} | sed 's/\\\\n/_!new_line!_/g') + + # remove newline characters + dispatch_inputs=$(echo ${dispatch_inputs} | sed 's/\\n//g') + + # replace placeholder with newline + dispatch_inputs=$(echo ${dispatch_inputs} | sed 's/_!new_line!_/\\n/g') + + # replace escaped quotes with unescaped quotes + dispatch_inputs=$(echo ${dispatch_inputs} | sed 's/\\"//g') + + # debug echo + echo "$dispatch_inputs" + + # parse as JSON + dispatch_inputs=$(echo "$dispatch_inputs" | jq -c .) + + # debug echo + echo "$dispatch_inputs" + + echo "dispatch_inputs=$dispatch_inputs" >> $GITHUB_OUTPUT + + - name: Workflow Dispatch + uses: benc-uk/workflow-dispatch@v1.2.2 + with: + repo: ${{ github.event.inputs.dispatch_repository }} + ref: ${{ github.event.inputs.dispatch_ref || 'master' }} # default to master if not specified + workflow: ${{ github.event.inputs.dispatch_workflow }} + inputs: ${{ steps.inputs.outputs.dispatch_inputs }} + token: ${{ secrets.GH_BOT_TOKEN || github.token }} # fallback to default token if not specified diff --git a/.github/workflows/issues-stale.yml b/.github/workflows/issues-stale.yml new file mode 100644 index 0000000..3ba3886 --- /dev/null +++ b/.github/workflows/issues-stale.yml @@ -0,0 +1,61 @@ +--- +# This action is centrally managed in https://github.com//.github/ +# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in +# the above-mentioned repo. + +# Manage stale issues and PRs. + +name: Stale Issues / PRs + +on: + schedule: + - cron: '00 10 * * *' + +jobs: + stale: + name: Check Stale Issues / PRs + if: startsWith(github.repository, 'LizardByte/') + runs-on: ubuntu-latest + steps: + - name: Stale + uses: actions/stale@v8 + with: + close-issue-message: > + This issue was closed because it has been stalled for 10 days with no activity. + close-pr-message: > + This PR was closed because it has been stalled for 10 days with no activity. + days-before-stale: 90 + days-before-close: 10 + exempt-all-assignees: true + exempt-issue-labels: 'added,fixed' + exempt-pr-labels: 'dependencies,l10n' + stale-issue-label: 'stale' + stale-issue-message: > + :wave: @{issue-author}, It seems this issue hasn't had any activity in the past 90 days. + If it's still something you'd like addressed, please let us know by leaving a comment. + Otherwise, to help keep our backlog tidy, we'll be closing this issue in 10 days. Thanks! + stale-pr-label: 'stale' + stale-pr-message: > + :wave: @{issue-author}, It looks like this PR has been idle for 90 days. + If it's still something you're working on or would like to pursue, + please leave a comment or update your branch. + Otherwise, we'll be closing this PR in 10 days to reduce our backlog. Thanks! + repo-token: ${{ secrets.GH_BOT_TOKEN }} + + - name: Invalid Template + uses: actions/stale@v8 + with: + close-issue-message: > + This issue was closed because the the template was not completed after 5 days. + close-pr-message: > + This PR was closed because the the template was not completed after 5 days. + days-before-stale: 0 + days-before-close: 5 + only-labels: 'invalid:template-incomplete' + stale-issue-label: 'invalid:template-incomplete' + stale-issue-message: > + Invalid issues template. + stale-pr-label: 'invalid:template-incomplete' + stale-pr-message: > + Invalid PR template. + repo-token: ${{ secrets.GH_BOT_TOKEN }} diff --git a/.github/workflows/issues.yml b/.github/workflows/issues.yml new file mode 100644 index 0000000..d7a1025 --- /dev/null +++ b/.github/workflows/issues.yml @@ -0,0 +1,25 @@ +--- +# This action is centrally managed in https://github.com//.github/ +# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in +# the above-mentioned repo. + +# Label and un-label actions using `../label-actions.yml`. + +name: Issues + +on: + issues: + types: [labeled, unlabeled] + discussion: + types: [labeled, unlabeled] + +jobs: + label: + name: Label Actions + if: startsWith(github.repository, 'LizardByte/') + runs-on: ubuntu-latest + steps: + - name: Label Actions + uses: dessant/label-actions@v3 + with: + github-token: ${{ secrets.GH_BOT_TOKEN }} diff --git a/.github/workflows/yaml-lint.yml b/.github/workflows/yaml-lint.yml new file mode 100644 index 0000000..7e1fd46 --- /dev/null +++ b/.github/workflows/yaml-lint.yml @@ -0,0 +1,66 @@ +--- +# This action is centrally managed in https://github.com//.github/ +# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in +# the above-mentioned repo. + +# Lint yaml files. + +name: yaml lint + +on: + pull_request: + branches: [master, nightly] + types: [opened, synchronize, reopened] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + yaml-lint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Find additional files + id: find-files + run: | + # space separated list of files + FILES=.clang-format + + # empty placeholder + FOUND="" + + for FILE in ${FILES}; do + if [ -f "$FILE" ] + then + FOUND="$FOUND $FILE" + fi + done + + echo "found=${FOUND}" >> $GITHUB_OUTPUT + + - name: yaml lint + id: yaml-lint + uses: ibiqlik/action-yamllint@v3 + with: + # https://yamllint.readthedocs.io/en/stable/configuration.html#default-configuration + config_data: | + extends: default + rules: + comments: + level: error + line-length: + max: 120 + truthy: + # GitHub uses "on" for workflow event triggers + # .clang-format file has options of "Yes" "No" that will be caught by this, so changed to "warning" + allowed-values: ['true', 'false', 'on'] + check-keys: true + level: warning + file_or_dir: . ${{ steps.find-files.outputs.found }} + + - name: Log + run: | + cat "${{ steps.yaml-lint.outputs.logfile }}" >> $GITHUB_STEP_SUMMARY