codeql-action/pr-checks/sync.py

146 строки
4.7 KiB
Python

import ruamel.yaml
import os
# The default set of CodeQL Bundle versions to use for the PR checks.
defaultTestVersions = [
# The oldest supported CodeQL version: 2.6.3. If bumping, update `CODEQL_MINIMUM_VERSION` in `codeql.ts`
"stable-20211005",
# The last CodeQL release in the 2.7 series: 2.7.6.
"stable-20220120",
# The last CodeQL release in the 2.8 series: 2.8.5.
"stable-20220401",
# The version of CodeQL currently in the toolcache. Typically either the latest release or the one before.
"cached",
# The latest release of CodeQL.
"latest",
# A nightly build directly from the our private repo, built in the last 24 hours.
"nightly-latest"
]
def isCompatibleWithLatestImages(version):
if version in ["cached", "latest", "nightly-latest"]:
return True
date = version.split("-")[1]
# The first version of the CodeQL CLI compatible with `ubuntu-22.04` and `windows-2022` is
# 2.8.2. This appears in CodeQL Bundle version codeql-bundle-20220224.
return date >= "20220224"
def operatingSystemsForVersion(version):
if isCompatibleWithLatestImages(version):
return ["ubuntu-latest", "macos-latest", "windows-latest"]
else:
return ["ubuntu-20.04", "macos-latest", "windows-2019"]
header = """# Warning: This file is generated automatically, and should not be modified.
# Instead, please modify the template in the pr-checks directory and run:
# pip install ruamel.yaml && python3 sync.py
# to regenerate this file.
"""
class NonAliasingRTRepresenter(ruamel.yaml.representer.RoundTripRepresenter):
def ignore_aliases(self, data):
return True
def writeHeader(checkStream):
checkStream.write(header)
yaml = ruamel.yaml.YAML()
yaml.Representer = NonAliasingRTRepresenter
allJobs = {}
for file in os.listdir('checks'):
with open(f"checks/{file}", 'r') as checkStream:
checkSpecification = yaml.load(checkStream)
matrix = []
for version in checkSpecification.get('versions', defaultTestVersions):
runnerImages = operatingSystemsForVersion(version)
if checkSpecification.get('operatingSystems', None):
runnerImages = [image for image in runnerImages for operatingSystem in checkSpecification['operatingSystems']
if image.startswith(operatingSystem)]
for runnerImage in runnerImages:
matrix.append({
'os': runnerImage,
'version': version
})
steps = [
{
'name': 'Check out repository',
'uses': 'actions/checkout@v3'
},
{
'name': 'Prepare test',
'id': 'prepare-test',
'uses': './.github/prepare-test',
'with': {
'version': '${{ matrix.version }}'
}
}
]
if any(not isCompatibleWithLatestImages(m['version']) for m in matrix):
steps.append({
'name': 'Set up Go',
'if': "matrix.os == 'ubuntu-20.04' || matrix.os == 'windows-2019'",
'uses': 'actions/setup-go@v4',
'with': {
'go-version': '^1.13.1'
}
})
steps.extend(checkSpecification['steps'])
checkJob = {
'strategy': {
'matrix': {
'include': matrix
}
},
'name': checkSpecification['name'],
'timeout-minutes': 45,
'runs-on': '${{ matrix.os }}',
'steps': steps
}
for key in ["env", "container", "services"]:
if key in checkSpecification:
checkJob[key] = checkSpecification[key]
checkJob['env'] = checkJob.get('env', {})
if 'CODEQL_ACTION_TEST_MODE' not in checkJob['env']:
checkJob['env']['CODEQL_ACTION_TEST_MODE'] = True
checkName = file[:len(file) - 4]
with open(f"../.github/workflows/__{checkName}.yml", 'w') as output_stream:
writeHeader(output_stream)
yaml.dump({
'name': f"PR Check - {checkSpecification['name']}",
'env': {
'GITHUB_TOKEN': '${{ secrets.GITHUB_TOKEN }}',
'GO111MODULE': 'auto',
# Disable Kotlin analysis while it's incompatible with Kotlin 1.8, until we find a
# workaround for our PR checks.
'CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN': 'true',
},
'on': {
'push': {
'branches': ['main', 'releases/v2']
},
'pull_request': {
'types': ["opened", "synchronize", "reopened", "ready_for_review"]
},
'workflow_dispatch': {}
},
'jobs': {
checkName: checkJob
}
}, output_stream)