[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [Git][tpo/applications/tor-browser-bundle-testsuite][main] Bug 40091: Implement script to trigger pipeline after nighly builds



Title: GitLab

brizental pushed to branch main at The Tor Project / Applications / tor-browser-bundle-testsuite

Commits:

  • 40d378be
    by Beatriz Rizental at 2026-04-29T13:47:55-03:00
    Bug 40091: Implement script to trigger pipeline after nighly builds
    

4 changed files:

Changes:

  • .gitignore
    ... ... @@ -6,3 +6,4 @@ virtualenv-marionette-*
    6 6
     reports
    
    7 7
     tmp
    
    8 8
     bundle
    
    9
    +tools/.gitlab_trigger_token

  • config/tb-build-06.torproject.org
    ... ... @@ -37,9 +37,10 @@ my $test_post = sub {
    37 37
         return unless $test->{publish_dir};
    
    38 38
     
    
    39 39
         my ($stdout, $stderr, $success) = capture_exec(
    
    40
    -        'python3', "$FindBin::Bin/tools/post-build-trigger.py",
    
    40
    +        'python3', "$FindBin::Bin/tools/trigger-test-pipeline.py",
    
    41 41
             '--step-name', $test->{name},
    
    42 42
             '--publish-url', $publish_url,
    
    43
    +        '--publish-dir', $test->{publish_dir},
    
    43 44
         );
    
    44 45
         print STDERR $stderr if $stderr;
    
    45 46
         if (!$success) {
    

  • tools/post-build-trigger.py deleted
    1
    -#!/usr/bin/env python3
    
    2
    -
    
    3
    -from __future__ import annotations
    
    4
    -
    
    5
    -import argparse
    
    6
    -import logging
    
    7
    -import sys
    
    8
    -
    
    9
    -
    
    10
    -logger = logging.getLogger(__name__)
    
    11
    -
    
    12
    -
    
    13
    -def setup_logging() -> None:
    
    14
    -    logging.basicConfig(
    
    15
    -        level=logging.INFO,
    
    16
    -        format="%(levelname)s: %(message)s",
    
    17
    -        # IMPORTANT!
    
    18
    -        #
    
    19
    -        # Perl captures this script's stdout and, if it is non-empty, stores it
    
    20
    -        # as `gitlab_pipeline_url` for the current build step. We need to keep logs
    
    21
    -        # on stderr and only print to stdout when its the resulting pipeline URL.
    
    22
    -        stream=sys.stderr,
    
    23
    -    )
    
    24
    -
    
    25
    -
    
    26
    -def parse_args() -> argparse.Namespace:
    
    27
    -    parser = argparse.ArgumentParser(
    
    28
    -        description="Post-build trigger hook for triggering GitLab CI pipelines."
    
    29
    -    )
    
    30
    -    parser.add_argument(
    
    31
    -        "--step-name",
    
    32
    -        required=True,
    
    33
    -        help="""
    
    34
    -            Name of the build step that just finished.
    
    35
    -            List of possible values can be found in
    
    36
    -            TBBTestSuite/TestSuite/TorBrowserBuild.pm (set_tests)
    
    37
    -            """,
    
    38
    -    )
    
    39
    -    parser.add_argument(
    
    40
    -        "--publish-url",
    
    41
    -        required=True,
    
    42
    -        help="URL where build artifacts are published for the build artifacts.",
    
    43
    -    )
    
    44
    -    return parser.parse_args()
    
    45
    -
    
    46
    -
    
    47
    -def main() -> int:
    
    48
    -    setup_logging()
    
    49
    -    args = parse_args()
    
    50
    -    logger.info(
    
    51
    -        f"post-build-trigger.py not implemented yet "
    
    52
    -        f"(step={args.step_name}, publish_url={args.publish_url})"
    
    53
    -    )
    
    54
    -    return 0
    
    55
    -
    
    56
    -
    
    57
    -if __name__ == "__main__":
    
    58
    -    raise SystemExit(main())

  • tools/trigger-test-pipeline.py
    1
    +#!/usr/bin/env python3
    
    2
    +import argparse
    
    3
    +import json
    
    4
    +import logging
    
    5
    +import os
    
    6
    +import sys
    
    7
    +import urllib.request
    
    8
    +
    
    9
    +logger = logging.getLogger(__name__)
    
    10
    +
    
    11
    +GITLAB_URL = "https://gitlab.torproject.org"
    
    12
    +# The project ID of the tor-browser-bundle-testsuite repository
    
    13
    +GITLAB_PROJECT_ID = "409"
    
    14
    +# We are running the pipeline on the main branch.
    
    15
    +GITLAB_REF = "main"
    
    16
    +
    
    17
    +SUPPORTED_ARCHITECTURES_PER_PLATFORM = {
    
    18
    +    "linux": ["x86_64"],
    
    19
    +    "windows": ["x86_64"],
    
    20
    +    "macos": ["x86_64"],
    
    21
    +    "android": ["x86_64"],
    
    22
    +}
    
    23
    +
    
    24
    +
    
    25
    +def setup_logging() -> None:
    
    26
    +    logging.basicConfig(
    
    27
    +        level=logging.INFO,
    
    28
    +        format="%(levelname)s: %(message)s",
    
    29
    +        # IMPORTANT!
    
    30
    +        #
    
    31
    +        # Perl captures this script's stdout and, if it is non-empty, stores it
    
    32
    +        # as `gitlab_pipeline_url` for the current build step. We need to keep logs
    
    33
    +        # on stderr and only print to stdout when its the resulting pipeline URL.
    
    34
    +        stream=sys.stderr,
    
    35
    +    )
    
    36
    +
    
    37
    +
    
    38
    +def parse_args() -> argparse.Namespace:
    
    39
    +    parser = argparse.ArgumentParser(
    
    40
    +        description="Post-build trigger hook for triggering GitLab CI pipelines."
    
    41
    +    )
    
    42
    +    parser.add_argument(
    
    43
    +        "--step-name",
    
    44
    +        required=True,
    
    45
    +        help="""
    
    46
    +            Name of the build step that just finished.
    
    47
    +            List of possible values can be found in
    
    48
    +            TBBTestSuite/TestSuite/TorBrowserBuild.pm (set_tests)
    
    49
    +            """,
    
    50
    +    )
    
    51
    +    parser.add_argument(
    
    52
    +        "--publish-url",
    
    53
    +        required=True,
    
    54
    +        help="URL where build artifacts are published for the build artifacts.",
    
    55
    +    )
    
    56
    +    parser.add_argument(
    
    57
    +        "--publish-dir",
    
    58
    +        required=True,
    
    59
    +        help="Subdirectory within the publish URL where build artifacts are located.",
    
    60
    +    )
    
    61
    +    parser.add_argument(
    
    62
    +        "--dry-run",
    
    63
    +        action="store_true",
    
    64
    +        help="Print the equivalent curl command instead of triggering the pipeline.",
    
    65
    +    )
    
    66
    +    return parser.parse_args()
    
    67
    +
    
    68
    +
    
    69
    +def build_inputs(step_name: str, publish_url: str, publish_dir: str) -> dict[str, str] | None:
    
    70
    +    # Add the architecture as padding, to address the macos case which doesn't
    
    71
    +    # have architecture in the step name since it is a universal build.
    
    72
    +    browser, channel, platform, architecture = (step_name.split("-") + ["x86_64"])[:4]
    
    73
    +    if channel != "nightly":
    
    74
    +        logger.info("This script only knows how to handle nightly builds. Skipping.")
    
    75
    +        return None
    
    76
    +    if (
    
    77
    +        platform not in SUPPORTED_ARCHITECTURES_PER_PLATFORM
    
    78
    +        or architecture not in SUPPORTED_ARCHITECTURES_PER_PLATFORM[platform]
    
    79
    +    ):
    
    80
    +        logger.info(
    
    81
    +            f"Tests for {platform}-{architecture} are not supported yet. Skipping."
    
    82
    +        )
    
    83
    +        return None
    
    84
    +
    
    85
    +    hyphenated_browser = "tor-browser" if browser == "torbrowser" else "mullvad-browser"
    
    86
    +    date = publish_url.rstrip("/").split("/")[-1].split(".", 1)[1]
    
    87
    +    match platform:
    
    88
    +        case "linux":
    
    89
    +            installer = f"{hyphenated_browser}-{platform}-{architecture}-tbb-{channel}.{date}.tar.xz"
    
    90
    +        case "windows":
    
    91
    +            installer = f"{hyphenated_browser}-{platform}-{architecture}-portable-tbb-{channel}.{date}.exe"
    
    92
    +        case "macos":
    
    93
    +            installer = f"{hyphenated_browser}-{platform}-{architecture}-tbb-{channel}.{date}.dmg"
    
    94
    +        case "android":
    
    95
    +            installer = f"{hyphenated_browser}-qa-{platform}-{architecture}-tbb-{channel}.{date}.apk"
    
    96
    +        case _:
    
    97
    +            raise ValueError(f"Unsupported platform: {platform!r}. How did we get here?")
    
    98
    +
    
    99
    +    artifacts_url = f"{publish_url}/{publish_dir}/artifacts/{platform}-{architecture}"
    
    100
    +    input_prefix = f"{'debian' if platform == 'linux' else platform}_{architecture}"
    
    101
    +    inputs = {
    
    102
    +        "mozharness_url": f"{artifacts_url}/mozharness.zip",
    
    103
    +        f"{input_prefix}_installer_url": f"{publish_url}/{publish_dir}/{installer}",
    
    104
    +        f"{input_prefix}_artifacts_url": artifacts_url,
    
    105
    +    }
    
    106
    +
    
    107
    +    if platform == "android":
    
    108
    +        inputs[f"{input_prefix}_package_name"] = f"org.torproject.{browser}_{channel}"
    
    109
    +
    
    110
    +    return inputs
    
    111
    +
    
    112
    +
    
    113
    +def dry_run(inputs: dict[str, str], trigger_token: str) -> None:
    
    114
    +    url = f"{GITLAB_URL}/api/v4/projects/{GITLAB_PROJECT_ID}/trigger/pipeline?token={trigger_token}&ref={GITLAB_REF}"
    
    115
    +    payload = json.dumps({"inputs": inputs}, indent=2)
    
    116
    +    print(
    
    117
    +        f"curl --request POST --header 'Content-Type: application/json' --data '{payload}' '{url}'"
    
    118
    +    )
    
    119
    +
    
    120
    +
    
    121
    +def trigger_pipeline(trigger_token: str, inputs: dict[str, str]) -> str:
    
    122
    +    url = f"{GITLAB_URL}/api/v4/projects/{GITLAB_PROJECT_ID}/trigger/pipeline"
    
    123
    +    payload = json.dumps(
    
    124
    +        {"token": trigger_token, "ref": GITLAB_REF, "inputs": inputs}
    
    125
    +    ).encode()
    
    126
    +    req = urllib.request.Request(
    
    127
    +        url,
    
    128
    +        data=payload,
    
    129
    +        headers={"Content-Type": "application/json"},
    
    130
    +        method="POST",
    
    131
    +    )
    
    132
    +    with urllib.request.urlopen(req) as resp:
    
    133
    +        data = json.loads(resp.read())
    
    134
    +
    
    135
    +    return data["web_url"]
    
    136
    +
    
    137
    +
    
    138
    +def main() -> int:
    
    139
    +    setup_logging()
    
    140
    +    args = parse_args()
    
    141
    +
    
    142
    +    token_file = os.path.join(
    
    143
    +        os.path.dirname(os.path.abspath(__file__)), ".gitlab_trigger_token"
    
    144
    +    )
    
    145
    +    with open(token_file) as f:
    
    146
    +        trigger_token = f.read().strip()
    
    147
    +
    
    148
    +    inputs = build_inputs(args.step_name, args.publish_url, args.publish_dir)
    
    149
    +    if inputs is None:
    
    150
    +        logger.info(f"No CI inputs for step {args.step_name!r}, skipping.")
    
    151
    +        return 0
    
    152
    +
    
    153
    +    if args.dry_run:
    
    154
    +        dry_run(inputs, trigger_token)
    
    155
    +        return 0
    
    156
    +
    
    157
    +    logger.info(f"Triggering pipeline for step={args.step_name!r}")
    
    158
    +    pipeline_url = trigger_pipeline(trigger_token, inputs)
    
    159
    +    logger.info(f"Pipeline triggered: {pipeline_url}")
    
    160
    +    print(pipeline_url)
    
    161
    +    return 0
    
    162
    +
    
    163
    +
    
    164
    +if __name__ == "__main__":
    
    165
    +    sys.exit(main())

  • _______________________________________________
    tor-commits mailing list -- tor-commits@xxxxxxxxxxxxxxxxxxxx
    To unsubscribe send an email to tor-commits-leave@xxxxxxxxxxxxxxxxxxxx