-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Cache and store primer packages via the default branch #6703
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
eb26fa9
29e49ae
30fec86
6c8592b
0e179f1
c5b0b4e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# Most of this is inspired by the mypy primer | ||
# See: https://github.com/hauntsaninja/mypy_primer | ||
# This is the primer job that runs on the default 'main' branch | ||
# It is also responsible for caching the packages to prime on | ||
|
||
name: Primer / Main | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
|
||
env: | ||
CACHE_VERSION: 1 | ||
|
||
jobs: | ||
run-primer: | ||
name: Run / ${{ matrix.python-version }} | ||
runs-on: ubuntu-latest | ||
timeout-minutes: 45 | ||
strategy: | ||
matrix: | ||
python-version: ["3.10"] | ||
DanielNoord marked this conversation as resolved.
Show resolved
Hide resolved
|
||
steps: | ||
- name: Check out code from GitHub | ||
uses: actions/[email protected] | ||
- name: Set up Python ${{ matrix.python-version }} | ||
id: python | ||
uses: actions/[email protected] | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
|
||
# Restore cached Python environment | ||
- name: Generate partial Python venv restore key | ||
id: generate-python-key | ||
run: >- | ||
echo "::set-output name=key::venv-${{ env.CACHE_VERSION }}-${{ | ||
hashFiles('setup.cfg', 'requirements_test.txt', 'requirements_test_min.txt') | ||
}}" | ||
- name: Restore Python virtual environment | ||
id: cache-venv | ||
uses: actions/[email protected] | ||
with: | ||
path: venv | ||
key: >- | ||
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ | ||
steps.generate-python-key.outputs.key }} | ||
restore-keys: | | ||
${{ runner.os }}-${{ steps.python.outputs.python-version }}-venv-${{ env.CACHE_VERSION }}- | ||
- name: Create Python virtual environment | ||
if: steps.cache-venv.outputs.cache-hit != 'true' | ||
run: | | ||
python -m venv venv | ||
. venv/bin/activate | ||
python -m pip install -U pip setuptools wheel | ||
pip install -U -r requirements_test.txt | ||
|
||
# Cache primer packages | ||
- name: Get commit string | ||
id: commitstring | ||
run: | | ||
. venv/bin/activate | ||
python tests/primer/primer_tool.py prepare --make-commit-string | ||
output=$(python tests/primer/primer_tool.py prepare --read-commit-string) | ||
echo "::set-output name=commitstring::$output" | ||
- name: Restore projects cache | ||
id: cache-projects | ||
uses: actions/cache@v3 | ||
with: | ||
path: .pylint_primer_tests/ | ||
key: >- | ||
${{ runner.os }}-${{ matrix.python-version }}-${{ | ||
steps.commitstring.outputs.commitstring }}-primer | ||
- name: Regenerate cache | ||
run: | | ||
. venv/bin/activate | ||
python tests/primer/primer_tool.py prepare --clone | ||
- name: Upload output diff | ||
uses: actions/upload-artifact@v3 | ||
with: | ||
name: primer_commitstring | ||
path: commit_string.txt |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
# Most of this is inspired by the mypy primer | ||
# See: https://github.com/hauntsaninja/mypy_primer | ||
# This is the primer job that runs on every PR | ||
|
||
name: Primer / Run | ||
|
||
on: | ||
pull_request: | ||
paths: | ||
- "pylint/**" | ||
- "tests/primer/**" | ||
- "requirements*" | ||
- ".github/workflows/**" | ||
|
||
env: | ||
CACHE_VERSION: 1 | ||
|
||
jobs: | ||
run-primer: | ||
name: Run / ${{ matrix.python-version }} | ||
runs-on: ubuntu-latest | ||
timeout-minutes: 120 | ||
strategy: | ||
matrix: | ||
python-version: ["3.10"] | ||
DanielNoord marked this conversation as resolved.
Show resolved
Hide resolved
|
||
steps: | ||
- name: Check out code from GitHub | ||
uses: actions/[email protected] | ||
- name: Set up Python ${{ matrix.python-version }} | ||
id: python | ||
uses: actions/[email protected] | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
- uses: actions/setup-node@v1 | ||
with: | ||
version: 12 | ||
- run: npm install @octokit/rest | ||
|
||
# Restore cached Python environment | ||
- name: Generate partial Python venv restore key | ||
id: generate-python-key | ||
run: >- | ||
echo "::set-output name=key::venv-${{ env.CACHE_VERSION }}-${{ | ||
hashFiles('setup.cfg', 'requirements_test.txt', 'requirements_test_min.txt') | ||
}}" | ||
- name: Restore Python virtual environment | ||
id: cache-venv | ||
uses: actions/[email protected] | ||
with: | ||
path: venv | ||
key: >- | ||
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ | ||
steps.generate-python-key.outputs.key }} | ||
restore-keys: | | ||
${{ runner.os }}-${{ steps.python.outputs.python-version }}-venv-${{ env.CACHE_VERSION }}- | ||
- name: Create Python virtual environment | ||
if: steps.cache-venv.outputs.cache-hit != 'true' | ||
run: | | ||
python -m venv venv | ||
. venv/bin/activate | ||
python -m pip install -U pip setuptools wheel | ||
pip install -U -r requirements_test.txt | ||
|
||
# Cache primer packages | ||
- name: Download diffs | ||
uses: actions/github-script@v6 | ||
with: | ||
script: | | ||
// Download 'main' pylint output | ||
const fs = require('fs'); | ||
const { Octokit } = require("@octokit/rest"); | ||
const octokit = new Octokit({}); | ||
const runs = await octokit.rest.actions.listWorkflowRuns({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
workflow_id: ".github/workflows/primer_run_main.yaml", | ||
status: "completed" | ||
}); | ||
const lastRunMain = runs.data.workflow_runs.reduce(function(prev, current) { | ||
return (prev.run_number > current.run_number) ? prev : current | ||
}) | ||
console.log("Last run on main:") | ||
console.log(lastRunMain.html_url) | ||
const artifacts_main = await github.rest.actions.listWorkflowRunArtifacts({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
run_id: lastRunMain.id, | ||
}); | ||
const [matchArtifactMain] = artifacts_main.data.artifacts.filter((artifact) => | ||
artifact.name == "primer_commitstring"); | ||
const downloadWorkflow = await github.rest.actions.downloadArtifact({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
artifact_id: matchArtifactMain.id, | ||
archive_format: "zip", | ||
}); | ||
fs.writeFileSync("primer_commitstring.zip", Buffer.from(downloadWorkflow.data)); | ||
- run: unzip primer_commitstring.zip | ||
- name: Get commit string | ||
id: commitstring | ||
run: | | ||
. venv/bin/activate | ||
output=$(python tests/primer/primer_tool.py prepare --read-commit-string) | ||
echo "::set-output name=commitstring::$output" | ||
- name: Restore projects cache | ||
id: cache-projects | ||
uses: actions/cache@v3 | ||
with: | ||
path: .pylint_primer_tests/ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we add a .gitignore to this directory to ensure it always exists? I'm thinking for local testing etc. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't this a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added! |
||
key: >- | ||
${{ runner.os }}-${{ matrix.python-version }}-${{ | ||
steps.commitstring.outputs.commitstring }}-primer | ||
- name: Check cache | ||
run: | | ||
. venv/bin/activate | ||
python tests/primer/primer_tool.py prepare --check | ||
|
||
- name: Save PR number | ||
run: | | ||
echo ${{ github.event.pull_request.number }} | tee pr_number.txt | ||
- name: Upload PR number | ||
uses: actions/upload-artifact@v2 | ||
with: | ||
name: primer_pylint_output_workflow | ||
path: pr_number.txt |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"astroid": { | ||
"branch": "main", | ||
"directories": ["astroid"], | ||
"url": "https://github.com/PyCQA/astroid" | ||
}, | ||
"black": { | ||
"branch": "main", | ||
"directories": ["src/black/", "src/blackd/", "src/blib2to3/"], | ||
"url": "https://github.com/psf/black.git" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html | ||
# For details: https://github.com/PyCQA/pylint/blob/main/LICENSE | ||
# Copyright (c) https://github.com/PyCQA/pylint/blob/main/CONTRIBUTORS.txt | ||
|
||
from __future__ import annotations | ||
|
||
import argparse | ||
import json | ||
from pathlib import Path | ||
|
||
import git | ||
|
||
from pylint.testutils.primer import PackageToLint | ||
|
||
MAIN_DIR = Path(__file__).parent.parent.parent | ||
PRIMER_DIRECTORY = MAIN_DIR / ".pylint_primer_tests/" | ||
PACKAGES_TO_PRIME_PATH = Path(__file__).parent / "packages_to_prime.json" | ||
|
||
|
||
class Primer: | ||
"""Main class to handle priming of packages.""" | ||
|
||
def __init__(self, package_list: Path) -> None: | ||
DanielNoord marked this conversation as resolved.
Show resolved
Hide resolved
|
||
# Preparing arguments | ||
self._argument_parser = argparse.ArgumentParser(prog="Pylint Primer") | ||
self._subparsers = self._argument_parser.add_subparsers(dest="command") | ||
|
||
# All arguments for the prepare parser | ||
prepare_parser = self._subparsers.add_parser("prepare") | ||
prepare_parser.add_argument( | ||
"--clone", help="Clone all packages.", action="store_true", default=False | ||
) | ||
prepare_parser.add_argument( | ||
"--check", | ||
help="Check consistencies and commits of all packages.", | ||
action="store_true", | ||
default=False, | ||
) | ||
prepare_parser.add_argument( | ||
"--make-commit-string", | ||
help="Get latest commit string.", | ||
action="store_true", | ||
default=False, | ||
) | ||
prepare_parser.add_argument( | ||
"--read-commit-string", | ||
help="Print latest commit string.", | ||
action="store_true", | ||
default=False, | ||
) | ||
|
||
# Storing arguments | ||
self.config = self._argument_parser.parse_args() | ||
|
||
self.packages = self._get_packages_to_lint_from_json(package_list) | ||
DanielNoord marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"""All packages to prime.""" | ||
|
||
def run(self) -> None: | ||
if self.config.command == "prepare": | ||
self._handle_prepare_command() | ||
|
||
def _handle_prepare_command(self) -> None: | ||
commit_string = "" | ||
if self.config.clone: | ||
for package, data in self.packages.items(): | ||
local_commit = data.lazy_clone() | ||
print(f"Cloned '{package}' at commit '{local_commit}'.") | ||
commit_string += local_commit + "_" | ||
elif self.config.check: | ||
for package, data in self.packages.items(): | ||
local_commit = git.Repo(data.clone_directory).head.object.hexsha | ||
print(f"Found '{package}' at commit '{local_commit}'.") | ||
commit_string += local_commit + "_" | ||
elif self.config.make_commit_string: | ||
for package, data in self.packages.items(): | ||
remote_sha1_commit = ( | ||
git.cmd.Git().ls_remote(data.url, data.branch).split("\t")[0] | ||
) | ||
print(f"'{package}' remote is at commit '{remote_sha1_commit}'.") | ||
commit_string += remote_sha1_commit + "_" | ||
elif self.config.read_commit_string: | ||
with open("commit_string.txt", encoding="utf-8") as f: | ||
print(f.read()) | ||
|
||
if commit_string: | ||
with open("commit_string.txt", "w", encoding="utf-8") as f: | ||
f.write(commit_string) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably should add to the project's .gitignore. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have changed this to go into the primer directory instead of writing to root. |
||
|
||
@staticmethod | ||
def _get_packages_to_lint_from_json(json_path: Path) -> dict[str, PackageToLint]: | ||
with open(json_path, encoding="utf8") as f: | ||
return { | ||
name: PackageToLint(**package_data) | ||
for name, package_data in json.load(f).items() | ||
} | ||
|
||
|
||
if __name__ == "__main__": | ||
primer = Primer(PACKAGES_TO_PRIME_PATH) | ||
primer.run() |
Uh oh!
There was an error while loading. Please reload this page.