Loading .gitlab-ci.pre-commit-run.bash +1 −1 Original line number Diff line number Diff line Loading @@ -44,7 +44,7 @@ pre_commit_run() ( fetch_ref $CI_COMMIT_BEFORE_SHA elif [[ -v CI_MERGE_REQUEST_TARGET_BRANCH_NAME ]]; then find_lca $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME $CI_MERGE_REQUEST_TARGET_BRANCH_NAME elif [[ $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH ]]; then elif [[ -v CI_COMMIT_BRANCH ]] && [[ $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH ]]; then find_lca $CI_COMMIT_BRANCH $CI_DEFAULT_BRANCH fi Loading tests/unit/gitlab_ci/pre_commit_run/fixtures.py +15 −19 Original line number Diff line number Diff line Loading @@ -28,11 +28,6 @@ from project_templates.resources import TempDir Ref = NewType("Ref", str) Sha = NewType("Sha", str) MAIN = Ref("main") FORK = Ref("fork") LCA = Ref("lca") ORPHAN = Ref("orphan") class Branch: """ Loading Loading @@ -80,7 +75,7 @@ class Repo: def __str__(self) -> str: return self.url def init(self, branch: str = MAIN) -> None: def init(self, branch: str = "main") -> None: """ Initialise (git-init) a bare repository, with "branch" checked out """ Loading Loading @@ -133,36 +128,37 @@ class Repo: return Sha(proc.stdout.decode().strip()) def setup_fixture_repo(repo: Repo) -> dict[Ref, Branch]: def setup_fixture_repo(repo: Repo) -> None: r""" Create a sample git repository as a test fixture The repository consists of three branches, two with common ancestors and one with no commonality with the other two: ┌──────────────────────────────────┐ ┌──────────────────────────────────────────┐ │ "lca" (Last common ancestor) │ │ ↓ │ │ ○─○─○─○─○─○─○─○─○─● "main" │ │ ○─○─○─○─○─○─○─○─○─● "main", tag:"test" │ │ └─○─○─○─○─● "fork" │ │ ○─○─○─○─○─○─○─○─○─● "orphan" │ └──────────────────────────────────┘ └──────────────────────────────────────────┘ """ random.seed(1) root = create_commit(repo) main = Branch(repo, MAIN, root) fork = Branch(repo, FORK, root) lca = Branch(repo, LCA, root) main = Branch(repo, "main", root) fork = Branch(repo, "fork", root) lca = Branch(repo, "lca", root) lca.head = create_commit_path(repo, root, 5) main.head = create_commit_path(repo, lca.head, 5) fork.head = create_commit_path(repo, lca.head, 5) orphan = Branch(repo, ORPHAN, create_commit(repo)) orphan = Branch(repo, "orphan", create_commit(repo)) orphan.head = create_commit_path(repo, orphan.root, 5) return {b.name: b for b in (main, fork, lca, orphan)} # Make test tag repo.command("tag", "test", main.head) def create_commit_path(repo: Repo, source: Sha, number: int) -> Sha: Loading tests/unit/gitlab_ci/pre_commit_run/runner.bash +17 −5 Original line number Diff line number Diff line Loading @@ -53,6 +53,10 @@ get_sha() { GIT_DIR=$1 git rev-parse --revs-only --verify $2 } get_ref_name() { sed 's@refs/[^/]\+/@@' <<<"$1" } get_head() { GIT_DIR=$1 git symbolic-ref HEAD | sed 's@refs/heads/@@' } Loading @@ -60,7 +64,7 @@ get_head() { # Handle arguments cd "${1? The directory to run from, this should be the top of the git repository}" source "${2? The full path to the Bash file containing pre_commit_run}" declare COMMIT_BRANCH=${3? Need the head reference of a target commmit} declare COMMIT_REF=${3? Need the head or tag reference of a target commit} declare SOURCE_REPO=${4? Need the path to the source repository fixture} shift 4 Loading @@ -76,18 +80,26 @@ declare -x CI_MERGE_REQUEST_TARGET_BRANCH_NAME # Set appropriate values for CI_* variables CI_REPOSITORY_URL=file://$SOURCE_REPO CI_DEFAULT_BRANCH=$(get_head $SOURCE_REPO) CI_COMMIT_SHA=$(get_sha $SOURCE_REPO $COMMIT_BRANCH) CI_COMMIT_SHA=$(get_sha $SOURCE_REPO $COMMIT_REF) case ${CI_PIPELINE_SOURCE:=push} in merge_request_event) assert '[[ ! -v CI_COMMIT_BEFORE_SHA ]]' \ "CI_COMMIT_BEFORE_SHA cannot be set for merge request pipelines" : ${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:=$CI_DEFAULT_BRANCH} CI_MERGE_REQUEST_SOURCE_BRANCH_NAME=$COMMIT_BRANCH CI_MERGE_REQUEST_SOURCE_BRANCH_NAME=$(get_ref_name $COMMIT_REF) CI_COMMIT_BEFORE_SHA=$NULL_SHA ;; *) CI_COMMIT_BRANCH=$COMMIT_BRANCH *) case $COMMIT_REF in refs/heads/*) CI_COMMIT_BRANCH=$(get_ref_name $COMMIT_REF) ;; refs/tags/*) CI_PIPELINE_SOURCE=push CI_COMMIT_TAG=$(get_ref_name $COMMIT_REF) ;; *) echo >&2 "Unrecognised reference type: $COMMIT_REF"; exit 2 ;; esac ;; esac Loading tests/unit/gitlab_ci/pre_commit_run/tests.py +27 −26 Original line number Diff line number Diff line Loading @@ -22,14 +22,7 @@ import subprocess import unittest from pathlib import Path from typing import Iterable from typing import Mapping from .fixtures import FORK from .fixtures import LCA from .fixtures import MAIN from .fixtures import ORPHAN from .fixtures import Branch from .fixtures import Ref from .fixtures import Repo from .fixtures import setup_fixture_repo Loading @@ -47,7 +40,6 @@ class PreCommitRunTests(unittest.TestCase): repo: Repo test_repo: Repo branches: Mapping[Ref, Branch] @classmethod def setUpClass(cls) -> None: Loading @@ -55,7 +47,7 @@ class PreCommitRunTests(unittest.TestCase): Prepare fixtures for the entire test case """ cls.repo = Repo(init=True) cls.branches = setup_fixture_repo(cls.repo) setup_fixture_repo(cls.repo) @classmethod def tearDownClass(cls) -> None: Loading Loading @@ -102,11 +94,11 @@ class PreCommitRunTests(unittest.TestCase): """ Check that calling with CI_COMMIT_BEFORE_SHA set ensures the commit is available """ from_sha = self.repo.get_sha(f"{MAIN}~4") to_sha = self.repo.get_sha(MAIN) from_sha = self.repo.get_sha("main~4") to_sha = self.repo.get_sha("main") args = self.run_script( MAIN, "refs/heads/main", CI_COMMIT_BEFORE_SHA=from_sha, ) Loading @@ -122,14 +114,14 @@ class PreCommitRunTests(unittest.TestCase): Check that calling in merge request pipelines finds the LCA with the target branch """ args = self.run_script( FORK, "refs/heads/fork", CI_PIPELINE_SOURCE="merge_request_event", ) expect = [ "run", f"--from-ref={self.branches[LCA].head}", f"--to-ref={self.repo.get_sha(FORK)}", f"--from-ref={self.repo.get_sha('lca')}", f"--to-ref={self.repo.get_sha('fork')}", ] self.assertListEqual(expect, args) Loading @@ -139,12 +131,12 @@ class PreCommitRunTests(unittest.TestCase): CI_COMMIT_BRANCH != CI_DEFAULT_BRANCH """ args = self.run_script(FORK) args = self.run_script("refs/heads/fork") expect = [ "run", f"--from-ref={self.branches[LCA].head}", f"--to-ref={self.repo.get_sha(FORK)}", f"--from-ref={self.repo.get_sha('lca')}", f"--to-ref={self.repo.get_sha('fork')}", ] self.assertListEqual(expect, args) Loading @@ -154,7 +146,7 @@ class PreCommitRunTests(unittest.TestCase): CI_COMMIT_BRANCH == CI_DEFAULT_BRANCH """ args = self.run_script(MAIN) args = self.run_script("refs/heads/main") expect = ["run", "--all-files"] self.assertListEqual(expect, args) Loading @@ -163,7 +155,16 @@ class PreCommitRunTests(unittest.TestCase): """ Check that pushing to a new orphan branch check all files """ args = self.run_script(ORPHAN) args = self.run_script("refs/heads/orphan") expect = ["run", "--all-files"] self.assertListEqual(expect, args) def test_tag(self) -> None: """ Check that pushing a tag works like pushing to a new branch """ args = self.run_script("refs/tags/test") expect = ["run", "--all-files"] self.assertListEqual(expect, args) Loading @@ -172,7 +173,7 @@ class PreCommitRunTests(unittest.TestCase): """ Check additional arguments passed to pre_commit_run are passed to pre-commit """ args = self.run_script(MAIN, ["more", "arguments"]) args = self.run_script("refs/heads/main", ["more", "arguments"]) expect = ["run", "more", "arguments", "--all-files"] self.assertListEqual(expect, args) Loading @@ -189,14 +190,14 @@ class PreCommitRunTests(unittest.TestCase): http: "fatal: error processing shallow info: 4" """ args = self.run_script( MAIN, "refs/heads/main", CI_PIPELINE_SOURCE="merge_request_event", CI_MERGE_REQUEST_TARGET_BRANCH_NAME=LCA, CI_MERGE_REQUEST_TARGET_BRANCH_NAME="lca", ) expect = [ "run", f"--from-ref={self.branches[LCA].head}", f"--to-ref={self.repo.get_sha(MAIN)}", f"--from-ref={self.repo.get_sha('lca')}", f"--to-ref={self.repo.get_sha('main')}", ] self.assertListEqual(expect, args) Loading
.gitlab-ci.pre-commit-run.bash +1 −1 Original line number Diff line number Diff line Loading @@ -44,7 +44,7 @@ pre_commit_run() ( fetch_ref $CI_COMMIT_BEFORE_SHA elif [[ -v CI_MERGE_REQUEST_TARGET_BRANCH_NAME ]]; then find_lca $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME $CI_MERGE_REQUEST_TARGET_BRANCH_NAME elif [[ $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH ]]; then elif [[ -v CI_COMMIT_BRANCH ]] && [[ $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH ]]; then find_lca $CI_COMMIT_BRANCH $CI_DEFAULT_BRANCH fi Loading
tests/unit/gitlab_ci/pre_commit_run/fixtures.py +15 −19 Original line number Diff line number Diff line Loading @@ -28,11 +28,6 @@ from project_templates.resources import TempDir Ref = NewType("Ref", str) Sha = NewType("Sha", str) MAIN = Ref("main") FORK = Ref("fork") LCA = Ref("lca") ORPHAN = Ref("orphan") class Branch: """ Loading Loading @@ -80,7 +75,7 @@ class Repo: def __str__(self) -> str: return self.url def init(self, branch: str = MAIN) -> None: def init(self, branch: str = "main") -> None: """ Initialise (git-init) a bare repository, with "branch" checked out """ Loading Loading @@ -133,36 +128,37 @@ class Repo: return Sha(proc.stdout.decode().strip()) def setup_fixture_repo(repo: Repo) -> dict[Ref, Branch]: def setup_fixture_repo(repo: Repo) -> None: r""" Create a sample git repository as a test fixture The repository consists of three branches, two with common ancestors and one with no commonality with the other two: ┌──────────────────────────────────┐ ┌──────────────────────────────────────────┐ │ "lca" (Last common ancestor) │ │ ↓ │ │ ○─○─○─○─○─○─○─○─○─● "main" │ │ ○─○─○─○─○─○─○─○─○─● "main", tag:"test" │ │ └─○─○─○─○─● "fork" │ │ ○─○─○─○─○─○─○─○─○─● "orphan" │ └──────────────────────────────────┘ └──────────────────────────────────────────┘ """ random.seed(1) root = create_commit(repo) main = Branch(repo, MAIN, root) fork = Branch(repo, FORK, root) lca = Branch(repo, LCA, root) main = Branch(repo, "main", root) fork = Branch(repo, "fork", root) lca = Branch(repo, "lca", root) lca.head = create_commit_path(repo, root, 5) main.head = create_commit_path(repo, lca.head, 5) fork.head = create_commit_path(repo, lca.head, 5) orphan = Branch(repo, ORPHAN, create_commit(repo)) orphan = Branch(repo, "orphan", create_commit(repo)) orphan.head = create_commit_path(repo, orphan.root, 5) return {b.name: b for b in (main, fork, lca, orphan)} # Make test tag repo.command("tag", "test", main.head) def create_commit_path(repo: Repo, source: Sha, number: int) -> Sha: Loading
tests/unit/gitlab_ci/pre_commit_run/runner.bash +17 −5 Original line number Diff line number Diff line Loading @@ -53,6 +53,10 @@ get_sha() { GIT_DIR=$1 git rev-parse --revs-only --verify $2 } get_ref_name() { sed 's@refs/[^/]\+/@@' <<<"$1" } get_head() { GIT_DIR=$1 git symbolic-ref HEAD | sed 's@refs/heads/@@' } Loading @@ -60,7 +64,7 @@ get_head() { # Handle arguments cd "${1? The directory to run from, this should be the top of the git repository}" source "${2? The full path to the Bash file containing pre_commit_run}" declare COMMIT_BRANCH=${3? Need the head reference of a target commmit} declare COMMIT_REF=${3? Need the head or tag reference of a target commit} declare SOURCE_REPO=${4? Need the path to the source repository fixture} shift 4 Loading @@ -76,18 +80,26 @@ declare -x CI_MERGE_REQUEST_TARGET_BRANCH_NAME # Set appropriate values for CI_* variables CI_REPOSITORY_URL=file://$SOURCE_REPO CI_DEFAULT_BRANCH=$(get_head $SOURCE_REPO) CI_COMMIT_SHA=$(get_sha $SOURCE_REPO $COMMIT_BRANCH) CI_COMMIT_SHA=$(get_sha $SOURCE_REPO $COMMIT_REF) case ${CI_PIPELINE_SOURCE:=push} in merge_request_event) assert '[[ ! -v CI_COMMIT_BEFORE_SHA ]]' \ "CI_COMMIT_BEFORE_SHA cannot be set for merge request pipelines" : ${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:=$CI_DEFAULT_BRANCH} CI_MERGE_REQUEST_SOURCE_BRANCH_NAME=$COMMIT_BRANCH CI_MERGE_REQUEST_SOURCE_BRANCH_NAME=$(get_ref_name $COMMIT_REF) CI_COMMIT_BEFORE_SHA=$NULL_SHA ;; *) CI_COMMIT_BRANCH=$COMMIT_BRANCH *) case $COMMIT_REF in refs/heads/*) CI_COMMIT_BRANCH=$(get_ref_name $COMMIT_REF) ;; refs/tags/*) CI_PIPELINE_SOURCE=push CI_COMMIT_TAG=$(get_ref_name $COMMIT_REF) ;; *) echo >&2 "Unrecognised reference type: $COMMIT_REF"; exit 2 ;; esac ;; esac Loading
tests/unit/gitlab_ci/pre_commit_run/tests.py +27 −26 Original line number Diff line number Diff line Loading @@ -22,14 +22,7 @@ import subprocess import unittest from pathlib import Path from typing import Iterable from typing import Mapping from .fixtures import FORK from .fixtures import LCA from .fixtures import MAIN from .fixtures import ORPHAN from .fixtures import Branch from .fixtures import Ref from .fixtures import Repo from .fixtures import setup_fixture_repo Loading @@ -47,7 +40,6 @@ class PreCommitRunTests(unittest.TestCase): repo: Repo test_repo: Repo branches: Mapping[Ref, Branch] @classmethod def setUpClass(cls) -> None: Loading @@ -55,7 +47,7 @@ class PreCommitRunTests(unittest.TestCase): Prepare fixtures for the entire test case """ cls.repo = Repo(init=True) cls.branches = setup_fixture_repo(cls.repo) setup_fixture_repo(cls.repo) @classmethod def tearDownClass(cls) -> None: Loading Loading @@ -102,11 +94,11 @@ class PreCommitRunTests(unittest.TestCase): """ Check that calling with CI_COMMIT_BEFORE_SHA set ensures the commit is available """ from_sha = self.repo.get_sha(f"{MAIN}~4") to_sha = self.repo.get_sha(MAIN) from_sha = self.repo.get_sha("main~4") to_sha = self.repo.get_sha("main") args = self.run_script( MAIN, "refs/heads/main", CI_COMMIT_BEFORE_SHA=from_sha, ) Loading @@ -122,14 +114,14 @@ class PreCommitRunTests(unittest.TestCase): Check that calling in merge request pipelines finds the LCA with the target branch """ args = self.run_script( FORK, "refs/heads/fork", CI_PIPELINE_SOURCE="merge_request_event", ) expect = [ "run", f"--from-ref={self.branches[LCA].head}", f"--to-ref={self.repo.get_sha(FORK)}", f"--from-ref={self.repo.get_sha('lca')}", f"--to-ref={self.repo.get_sha('fork')}", ] self.assertListEqual(expect, args) Loading @@ -139,12 +131,12 @@ class PreCommitRunTests(unittest.TestCase): CI_COMMIT_BRANCH != CI_DEFAULT_BRANCH """ args = self.run_script(FORK) args = self.run_script("refs/heads/fork") expect = [ "run", f"--from-ref={self.branches[LCA].head}", f"--to-ref={self.repo.get_sha(FORK)}", f"--from-ref={self.repo.get_sha('lca')}", f"--to-ref={self.repo.get_sha('fork')}", ] self.assertListEqual(expect, args) Loading @@ -154,7 +146,7 @@ class PreCommitRunTests(unittest.TestCase): CI_COMMIT_BRANCH == CI_DEFAULT_BRANCH """ args = self.run_script(MAIN) args = self.run_script("refs/heads/main") expect = ["run", "--all-files"] self.assertListEqual(expect, args) Loading @@ -163,7 +155,16 @@ class PreCommitRunTests(unittest.TestCase): """ Check that pushing to a new orphan branch check all files """ args = self.run_script(ORPHAN) args = self.run_script("refs/heads/orphan") expect = ["run", "--all-files"] self.assertListEqual(expect, args) def test_tag(self) -> None: """ Check that pushing a tag works like pushing to a new branch """ args = self.run_script("refs/tags/test") expect = ["run", "--all-files"] self.assertListEqual(expect, args) Loading @@ -172,7 +173,7 @@ class PreCommitRunTests(unittest.TestCase): """ Check additional arguments passed to pre_commit_run are passed to pre-commit """ args = self.run_script(MAIN, ["more", "arguments"]) args = self.run_script("refs/heads/main", ["more", "arguments"]) expect = ["run", "more", "arguments", "--all-files"] self.assertListEqual(expect, args) Loading @@ -189,14 +190,14 @@ class PreCommitRunTests(unittest.TestCase): http: "fatal: error processing shallow info: 4" """ args = self.run_script( MAIN, "refs/heads/main", CI_PIPELINE_SOURCE="merge_request_event", CI_MERGE_REQUEST_TARGET_BRANCH_NAME=LCA, CI_MERGE_REQUEST_TARGET_BRANCH_NAME="lca", ) expect = [ "run", f"--from-ref={self.branches[LCA].head}", f"--to-ref={self.repo.get_sha(MAIN)}", f"--from-ref={self.repo.get_sha('lca')}", f"--to-ref={self.repo.get_sha('main')}", ] self.assertListEqual(expect, args)