Feature/dmtlint #592
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# THIS FILE IS GENERATED, PLEASE DO NOT EDIT. | |
# | |
# Copyright 2022 Flant JSC | |
# | |
# 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.# Run validation script on every push to dev branches. | |
# | |
# Validation scripts require PR title, PR description and diff. | |
# Title and description are available when PR is already created. | |
# Diff content is fetched using 'diff_url' field in payload when PR is available. | |
# If PR is not created, 'compare' field is used to get diff between base branch and dev branch. | |
# | |
# See also scripts/validation_run.sh. | |
# | |
name: Validations | |
on: | |
pull_request_target: | |
types: | |
- opened | |
- synchronize | |
# Cancel in-progress jobs for the same PR (pull_request_target event) or for the same branch (push event). | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.event.number || github.ref }} | |
cancel-in-progress: true | |
jobs: | |
close_dependabot_prs_for_forks: | |
name: Autoclose Dependabot PRs for forks | |
runs-on: ubuntu-24.04 | |
if: ${{ github.actor == 'dependabot[bot]' && github.repository != 'deckhouse/deckhouse' }} | |
env: | |
ENABLE_DEPENDABOT_IN_FORKS: ${{ secrets.ENABLE_DEPENDABOT_IN_FORKS }} | |
steps: | |
- name: Close PR | |
uses: actions/github-script@v6.4.1 | |
with: | |
github-token: ${{ secrets.BOATSWAIN_GITHUB_TOKEN }} | |
script: | | |
// Keep PR if explicitly enabled. | |
const {ENABLE_DEPENDABOT_IN_FORKS} = process.env; | |
const prNum = context.payload.pull_request.number; | |
const repo = context.payload.repository.full_name; | |
if (ENABLE_DEPENDABOT_IN_FORKS === 'true') { | |
core.info(`Secret ENABLE_DEPENDABOT_IN_FORKS is 'true', proceed with validation for PR#${prNUM} in repo ${repo}.`); | |
return | |
} | |
core.info(`Secret ENABLE_DEPENDABOT_IN_FORKS is not 'true', close PR#${prNum} in repo ${repo}.`); | |
return await github.rest.pulls.update({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
pull_number: prNum, | |
state: 'closed' | |
}); | |
# <template: pull_request_info> | |
pull_request_info: | |
name: Get pull request reference | |
runs-on: ubuntu-latest | |
outputs: | |
ref: ${{ steps.pr_props.outputs.ref }} | |
ref_slug: ${{ steps.pr_props.outputs.ref_slug }} | |
edition: ${{ steps.pr_props.outputs.edition }} | |
pr_title: ${{ steps.pr_props.outputs.pr_title }} | |
pr_description: ${{ steps.pr_props.outputs.pr_description }} | |
diff_url: ${{ steps.pr_props.outputs.diff_url }} | |
labels: ${{ steps.pr_props.outputs.labels }} | |
changes_docs: ${{ steps.changes.outputs.docs }} | |
changes_not_markdown: ${{ steps.changes.outputs.not_markdown }} | |
# Skip pull_request and pull_request_target triggers for PRs authored by deckhouse-BOaTswain, e.g. changelog PRs. | |
if: ${{ ! (startsWith(github.event_name, 'pull_request') && github.event.pull_request.user.login == 'deckhouse-BOaTswain') }} | |
steps: | |
- name: Get PR info for push trigger | |
id: push_info | |
if: ${{ github.event_name == 'push' }} | |
uses: actions/github-script@v6.4.1 | |
with: | |
script: | | |
// Support for 'push' trigger: find PR by commit SHA and pass response to pr_props step. | |
const { GITHUB_REF_NAME } = process.env | |
core.startGroup(`Fetching PR info for commit ${context.sha} in ${context.repo.name}:${GITHUB_REF_NAME} ...`) | |
try { | |
const response = await github.rest.repos.listPullRequestsAssociatedWithCommit({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
commit_sha: context.sha | |
}); | |
if (response.status !== 200 || !response.data || response.data.length === 0) { | |
return core.setFailed(`Bad response on listing PRs for commit ${context.sha}: ${JSON.stringify(response)}`); | |
} | |
// Get first associated pr. | |
let pr = response.data[0]; | |
core.info(`Current labels: ${JSON.stringify(pr.labels)}`); | |
// Reduce size to fit output limits. | |
pr = { | |
url: pr.url, | |
diff_url: pr.diff_url, | |
number: pr.number, | |
labels: pr.labels, | |
head: pr.head, | |
title: pr.title, | |
body: pr.body, | |
} | |
core.notice(`Found PR#{pr.number} for commit ${context.sha}`); | |
core.setOutput('pr_info', JSON.stringify(pr)); | |
} catch (error) { | |
return core.setFailed(`Error listing pull requests for commit ${context.sha}: ${error}`) | |
} finally { | |
core.endGroup() | |
} | |
- name: Get PR info for pull_request trigger | |
id: pr_info | |
if: ${{ startsWith(github.event_name, 'pull_request') }} | |
uses: actions/github-script@v6.4.1 | |
with: | |
script: | | |
// Support for 'pull_request' and 'pull_request_target' triggers: | |
// find PR by its number to get current labels. | |
// Why? Workflow rerun of 'opened' pull request contains outdated labels. | |
const prNumber = context.payload.pull_request.number; | |
const owner = context.repo.owner; | |
const repo = context.repo.repo; | |
core.startGroup(`Fetching info for PR#${prNumber} ...`); | |
try { | |
const response = await github.rest.pulls.get({owner, repo, pull_number: prNumber}) | |
if (response.status != 200 || !response.data) { | |
return core.setFailed(`Bad response on getting PR#${prNumber} : ${JSON.stringify(response)}`); | |
} | |
// Only labels are needed. | |
let pr = response.data; | |
core.info(`Labels from context: ${JSON.stringify(context.payload.pull_request.labels)}`); | |
core.info(`Current labels: ${JSON.stringify(pr.labels)}`); | |
// Reduce size to fit output limits. | |
pr = { | |
url: pr.url, | |
diff_url: pr.diff_url, | |
number: pr.number, | |
labels: pr.labels, | |
head: pr.head, | |
title: pr.title, | |
body: pr.body, | |
} | |
core.setOutput('pr_info', JSON.stringify(pr)); | |
} catch (error) { | |
return core.setFailed(`Fetch PR#${prNumber} error: ${error}`) | |
} finally { | |
core.endGroup() | |
} | |
- name: Check PR properties | |
id: pr_props | |
uses: actions/github-script@v6.4.1 | |
env: | |
PR_INFO: ${{ steps.push_info.outputs.pr_info || steps.pr_info.outputs.pr_info }} | |
with: | |
script: | | |
if (process.env.PR_INFO == '') { | |
return core.setFailed(`No pull request info: event_name=${context.eventName} action=${context.action} ref=${context.ref}`); | |
} | |
// Parse Pr info from environment variable. | |
const pr = JSON.parse(process.env.PR_INFO); | |
core.startGroup(`Detect PR properties`) | |
const pr_repo = pr.head.repo.full_name; | |
const target_repo = context.payload.repository.full_name; | |
const isInternal = pr_repo === target_repo; | |
const isDependabot = (context.actor === 'dependabot[bot]'); | |
const isChangelog = pr.head.ref.startsWith('changelog/v'); | |
const okToTest = pr.labels.some((l) => l.name === 'status/ok-to-test'); | |
core.info(`PR head repo ${pr_repo}`) | |
core.info(`PR commit SHA ${pr.head.sha}`) | |
core.info(`PR head label ${pr.head.label}`) | |
core.info(`Target repo ${target_repo}`) | |
core.info(`PR internal? ${isInternal}`) | |
core.info(`PR from dependabot? ${isDependabot}`) | |
core.info(`PR changelog? ${isChangelog}`) | |
core.info(`PR has 'ok-to-test'? ${okToTest}`) | |
core.endGroup() | |
// Detect if PR can be ignored or should be checked for dangerous changes. | |
let shouldCheckFiles = false; | |
if (isInternal && !isDependabot) { | |
// Ignore changelog pull requests. | |
if (isChangelog) { | |
return core.setFailed(`PR#${pr.number} for changelog is ignored.`); | |
} | |
} else { | |
// External and dependabot pull requests should be labeled with 'status/ok-to-test'. | |
if (!okToTest) { | |
core.notice(`PR#${pr.number} requires label 'status/ok-to-test' to run tests and validations`) | |
return core.setFailed(`PR#${pr.number} without label 'status/ok-to-test' is ignored.`); | |
} | |
shouldCheckFiles = true; | |
} | |
if (shouldCheckFiles) { | |
core.notice(`PR#{pr.number} may be dangerous, will check file changes.`) | |
} | |
// Set edition from current labels. | |
const defaultEdition = process.env.WERF_ENV ? process.env.WERF_ENV : 'FE'; | |
const hasEE = pr.labels.some((l) => l.name === 'edition/ee'); | |
const hasCE = pr.labels.some((l) => l.name === 'edition/ce'); | |
const hasBE = pr.labels.some((l) => l.name === 'edition/be'); | |
const hasSE = pr.labels.some((l) => l.name === 'edition/se'); | |
const hasSE_plus = pr.labels.some((l) => l.name === 'edition/se+'); | |
let edition = defaultEdition; | |
if (hasCE) { | |
edition = 'CE'; | |
} else if (hasEE) { | |
edition = 'EE'; | |
} else if (hasBE) { | |
edition = 'BE'; | |
} else if (hasSE) { | |
edition = 'SE'; | |
} else if (hasSE_plus) { | |
edition = 'SE-plus'; | |
} | |
core.info(`Edition labels: 'edition/ce':${hasCE}, 'edition/ee':${hasEE}, 'edition/be':${hasBE}, 'edition/se':${hasSE}, 'edition/se+':${hasSE_plus}`); | |
core.notice(`Enable '${edition}' edition for '${context.eventName}' trigger.`); | |
// Construct head commit ref using pr number. | |
const ref = `refs/pull/${ pr.number }/head`; | |
core.notice(`Use ref: '${ref}'`) | |
// Pass pr.diff_url to download diff via regular request. | |
// Pass pr.url to get diff via API request. | |
let diff_url = pr.diff_url; | |
if (!!context.payload.repository.private) { | |
core.notice(`Detect private repo. Pass PR url to download diff via Github API.`); | |
diff_url = pr.url; | |
} | |
// Set outputs. | |
core.setCommandEcho(true) | |
core.setOutput('should_check', shouldCheckFiles.toString()); | |
core.setOutput('ref', ref); | |
core.setOutput('ref_slug', `pr${pr.number}`); | |
core.setOutput('edition', edition); | |
core.setOutput('pr_title', pr.title); | |
core.setOutput('pr_description', pr.body); | |
core.setOutput('diff_url', diff_url); | |
core.setOutput('labels', JSON.stringify(pr.labels)); | |
core.setCommandEcho(false); | |
# Checkhout the head commit of the PR branch. | |
- name: Checkout PR head commit | |
if: steps.pr_props.outputs.should_check == 'true' | |
uses: actions/checkout@v3.5.2 | |
with: | |
ref: ${{ steps.pr_props.outputs.ref }} | |
# Get info about other changes. | |
- name: Get info about PR changes | |
uses: dorny/paths-filter@v2 | |
id: changes | |
with: | |
token: ${{ secrets.BOATSWAIN_GITHUB_TOKEN }} | |
# dangerous - detect if changes not allowed to test for external PRs | |
# docs - detect changes in files that belong to the documentation scope | |
# not_markdown - detect changes not in markdown files | |
filters: | | |
dangerous: | |
- './.github/**' | |
- './tools/**' | |
- './testing/**' | |
- './docs/**/js/**' | |
- './docs/**/css/**' | |
- './docs/**/images/**' | |
- './docs/**/assets/**' | |
docs: | |
- './**/*.md' | |
- './docs/**' | |
- './**/crds/*' | |
- './**/openapi/*config-values.yaml' | |
- './candi/**/openapi/*' | |
- './ee/candi/**/openapi/*' | |
not_markdown: | |
- '!./**/*.md' | |
# Stop workflow if external PR contains dangerous changes. | |
- name: Fail workflow on dangerous changes | |
if: ${{ steps.pr_props.outputs.should_check == 'true' && steps.changes.outputs.dangerous == 'true' }} | |
uses: actions/github-script@v6.4.1 | |
with: | |
script: | | |
core.setFailed('External PR contains dangerous changes.') | |
# </template: pull_request_info> | |
# Get pull request info for validation scripts. | |
# Push event has no pull request information, so retrieve it with Rest API. | |
discover: | |
name: Prepare input for validation scripts | |
needs: | |
- pull_request_info | |
runs-on: ubuntu-24.04 | |
outputs: | |
run_no_cyrillic: ${{ steps.check_labels.outputs.run_no_cyrillic }} | |
label_no_cyrillic: ${{ steps.check_labels.outputs.label_no_cyrillic }} | |
run_doc_changes: ${{ steps.check_labels.outputs.run_doc_changes }} | |
label_doc_changes: ${{ steps.check_labels.outputs.label_doc_changes }} | |
run_copyright: ${{ steps.check_labels.outputs.run_copyright }} | |
label_copyright: ${{ steps.check_labels.outputs.label_copyright }} | |
run_markdown: ${{ steps.check_labels.outputs.run_markdown }} | |
label_markdown: ${{ steps.check_labels.outputs.label_markdown }} | |
run_grafana_dashboard: ${{ steps.check_labels.outputs.run_grafana_dashboard }} | |
label_grafana_dashboard: ${{ steps.check_labels.outputs.label_grafana_dashboard }} | |
run_release_requirements: ${{ steps.check_labels.outputs.run_release_requirements }} | |
label_release_requirements: ${{ steps.check_labels.outputs.label_release_requirements }} | |
steps: | |
# <template: checkout_step> | |
- name: Checkout sources | |
uses: actions/checkout@v3.5.2 | |
with: | |
ref: ${{ needs.pull_request_info.outputs.ref }} | |
# </template: checkout_step> | |
- id: check_labels | |
name: Check labels on push | |
uses: actions/github-script@v6.4.1 | |
env: | |
PR_LABELS: ${{ needs.pull_request_info.outputs.labels }} | |
with: | |
github-token: ${{ secrets.GITHUB_TOKEN }} | |
script: | | |
const labels = JSON.parse(process.env.PR_LABELS) | |
const ci = require('./.github/scripts/js/ci'); | |
return ci.checkValidationLabels({ core, labels }); | |
- name: Download diff for pull request | |
env: | |
DIFF_URL: ${{ needs.pull_request_info.outputs.diff_url }} | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: | | |
./.github/scripts/validation_run.sh --download-only ./pr.diff | |
- name: Upload diff as artifact | |
uses: actions/upload-artifact@v4.4.0 | |
with: | |
name: pr_diff | |
path: pr.diff | |
no_cyrillic_validation: | |
name: No Cyrillic Validation | |
env: | |
VALIDATE_TITLE: ${{ needs.pull_request_info.outputs.pr_title }} | |
VALIDATE_DESCRIPTION: ${{ needs.pull_request_info.outputs.pr_description }} | |
needs: | |
- discover | |
- pull_request_info | |
if: needs.discover.outputs.run_no_cyrillic == 'true' | |
runs-on: ubuntu-24.04 | |
steps: | |
# <template: checkout_step> | |
- name: Checkout sources | |
uses: actions/checkout@v3.5.2 | |
with: | |
ref: ${{ needs.pull_request_info.outputs.ref }} | |
# </template: checkout_step> | |
- name: Restore diff artifact | |
uses: actions/download-artifact@v4.1.8 | |
with: | |
name: pr_diff | |
- name: Run check | |
env: | |
DIFF_PATH: ./pr.diff | |
SKIP_LABEL_NAME: ${{ needs.discover.outputs.label_no_cyrillic }} | |
run: | | |
./.github/scripts/validation_run.sh ./testing/validate_no_cyrillic.sh | |
doc_validation: | |
name: Docs Validation (base) | |
needs: | |
- discover | |
- pull_request_info | |
if: needs.discover.outputs.run_doc_changes == 'true' | |
runs-on: ubuntu-24.04 | |
steps: | |
# <template: checkout_step> | |
- name: Checkout sources | |
uses: actions/checkout@v3.5.2 | |
with: | |
ref: ${{ needs.pull_request_info.outputs.ref }} | |
# </template: checkout_step> | |
- name: Restore diff artifact | |
uses: actions/download-artifact@v4.1.8 | |
with: | |
name: pr_diff | |
- name: Run check | |
env: | |
DIFF_PATH: ./pr.diff | |
SKIP_LABEL_NAME: ${{ needs.discover.outputs.label_doc_changes }} | |
run: | | |
./.github/scripts/validation_run.sh ./testing/validate_doc_changes.sh | |
doc_spell_check: | |
name: Docs Validation (spellcheck) | |
needs: | |
- discover | |
- pull_request_info | |
if: ${{ needs.discover.outputs.run_doc_changes == 'true' && github.repository == 'deckhouse/deckhouse' }} | |
runs-on: ubuntu-24.04 | |
steps: | |
# <template: checkout_step> | |
- name: Checkout sources | |
uses: actions/checkout@v3.5.2 | |
with: | |
ref: ${{ needs.pull_request_info.outputs.ref }} | |
# </template: checkout_step> | |
# <template: login_dev_registry_step> | |
- name: Check dev registry credentials | |
id: check_dev_registry | |
env: | |
HOST: ${{secrets.DECKHOUSE_DEV_REGISTRY_HOST}} | |
run: | | |
if [[ -n $HOST ]]; then | |
echo "has_credentials=true" >> $GITHUB_OUTPUT | |
echo "web_registry_path=${{secrets.DECKHOUSE_DEV_REGISTRY_HOST }}/deckhouse/site" >> $GITHUB_OUTPUT | |
fi | |
- name: Login to dev registry | |
uses: docker/login-action@v2.1.0 | |
if: ${{ steps.check_dev_registry.outputs.has_credentials == 'true' }} | |
with: | |
registry: ${{ secrets.DECKHOUSE_DEV_REGISTRY_HOST }} | |
username: ${{ secrets.DECKHOUSE_DEV_REGISTRY_USER }} | |
password: ${{ secrets.DECKHOUSE_DEV_REGISTRY_PASSWORD }} | |
logout: false | |
# </template: login_dev_registry_step> | |
- name: Restore diff artifact | |
uses: actions/download-artifact@v4.1.8 | |
with: | |
name: pr_diff | |
# <template: spellcheck_template> | |
- name: Install werf | |
uses: werf/actions/install@v1.2 | |
- name: Spell check | |
run: | | |
make lint-doc-spellcheck-pr | |
# </template: spellcheck_template> | |
copyright_validation: | |
name: Copyright Validation | |
needs: | |
- discover | |
- pull_request_info | |
if: needs.discover.outputs.run_copyright == 'true' | |
runs-on: ubuntu-24.04 | |
steps: | |
# <template: checkout_step> | |
- name: Checkout sources | |
uses: actions/checkout@v3.5.2 | |
with: | |
ref: ${{ needs.pull_request_info.outputs.ref }} | |
# </template: checkout_step> | |
- name: Restore diff artifact | |
uses: actions/download-artifact@v4.1.8 | |
with: | |
name: pr_diff | |
- name: Run check | |
env: | |
DIFF_PATH: ./pr.diff | |
SKIP_LABEL_NAME: ${{ needs.discover.outputs.label_copyright }} | |
run: | | |
./.github/scripts/validation_run.sh ./testing/validate_copyright.sh | |
grafana_dashboard_validation: | |
name: Grafana Dashboard Validation | |
needs: | |
- discover | |
- pull_request_info | |
if: needs.discover.outputs.run_grafana_dashboard == 'true' | |
runs-on: ubuntu-24.04 | |
steps: | |
# <template: checkout_step> | |
- name: Checkout sources | |
uses: actions/checkout@v3.5.2 | |
with: | |
ref: ${{ needs.pull_request_info.outputs.ref }} | |
# </template: checkout_step> | |
- name: Restore diff artifact | |
uses: actions/download-artifact@v4.1.8 | |
with: | |
name: pr_diff | |
- name: Run check | |
env: | |
DIFF_PATH: ./pr.diff | |
SKIP_LABEL_NAME: ${{ needs.discover.outputs.label_grafana_dashboard }} | |
run: | | |
./.github/scripts/validation_run.sh ./testing/validate_grafana_dashboard.sh | |
markdown_linter: | |
name: Markdown Linter | |
needs: | |
- discover | |
- pull_request_info | |
if: needs.discover.outputs.run_markdown == 'true' | |
runs-on: ubuntu-24.04 | |
steps: | |
# <template: checkout_step> | |
- name: Checkout sources | |
uses: actions/checkout@v3.5.2 | |
with: | |
ref: ${{ needs.pull_request_info.outputs.ref }} | |
# </template: checkout_step> | |
- name: Restore diff artifact | |
uses: actions/download-artifact@v4.1.8 | |
with: | |
name: pr_diff | |
- name: Run linter | |
env: | |
DIFF_PATH: ./pr.diff | |
SKIP_LABEL_NAME: ${{ needs.discover.outputs.label_markdown }} | |
run: | | |
make lint-markdown | |
release_requirements_validation: | |
name: Release Requirements Validation | |
needs: | |
- discover | |
- pull_request_info | |
if: needs.discover.outputs.run_release_requirements == 'true' | |
runs-on: ubuntu-24.04 | |
steps: | |
# <template: checkout_step> | |
- name: Checkout sources | |
uses: actions/checkout@v3.5.2 | |
with: | |
ref: ${{ needs.pull_request_info.outputs.ref }} | |
# </template: checkout_step> | |
- name: Restore diff artifact | |
uses: actions/download-artifact@v4.1.8 | |
with: | |
name: pr_diff | |
- name: Run check | |
env: | |
DIFF_PATH: ./pr.diff | |
SKIP_LABEL_NAME: ${{ needs.discover.outputs.label_release_requirements }} | |
run: | | |
./.github/scripts/validation_run.sh ./testing/validate_release_requirements.sh | |