--- a/grants.yml
+++ b/grants.yml
@@ -811,17 +811,17 @@
feature: trust-domain-scopes
- grant:
# routes to support indexing by product
- queue:route:index.{trust_domain}.v2.{alias}-pr.*
- index:insert-task:{trust_domain}.v2.{alias}-pr.*
to:
- project:
- job: [pull-request]
+ job: [pull-request:*]
feature: trust-domain-scopes
- grant:
# routes to support reporting to treeherder
- queue:route:tc-treeherder-stage.{alias}.*
- queue:route:tc-treeherder.{alias}.*
- queue:route:tc-treeherder-stage.v2.{alias}.*
- queue:route:tc-treeherder.v2.{alias}.*
@@ -831,17 +831,17 @@
include_pull_requests: false
- grant:
# routes to support reporting to treeherder
- queue:route:tc-treeherder-stage.v2.{alias}-pr.*
- queue:route:tc-treeherder.v2.{alias}-pr.*
to:
- project:
- job: [pull-request]
+ job: [pull-request:*]
feature: treeherder-reporting
- grant:
- queue:create-task:{priority}:hg-t/*
- queue:route:notify.irc-channel.*
- queue:route:tc-treeherder.v2.version-control-tools.*
to:
@@ -856,16 +856,17 @@
- project:
trust_domain: [taskgraph, ci]
- grant:
- secrets:get:project/releng/taskgraph/ci
to:
- project:
alias: taskgraph
+ job: [action:*, branch:*, pull-request:trusted, release]
- grant:
- secrets:get:project/releng/shipit/ci
to:
- project:
alias: shipit
##
@@ -980,25 +981,25 @@
# - scriptworker specific roles
- grant:
- secrets:get:repo:github.com/mozilla-releng/scriptworker:coveralls
- secrets:get:repo:github.com/mozilla-releng/scriptworker:github
to:
- project:
alias: scriptworker
- job: [pull-request, branch:main]
+ job: [pull-request:trusted, branch:main]
# - balrog specific roles
- grant:
- secrets:get:repo:github.com/mozilla-releng/balrog:coveralls
to:
- project:
alias: balrog
- job: [pull-request, branch:master, branch:main]
+ job: [pull-request:*, branch:master, branch:main]
- grant:
- queue:route:index.project.balrog.*
- queue:route:notify.*
- secrets:get:repo:github.com/mozilla-releng/balrog:dockerhub
to:
- project:
alias: balrog
@@ -1049,17 +1050,17 @@
job: [branch:master, branch:production]
# - occ specific roles
- grant:
- queue:route:index.project.releng.opencloudconfig.v1.revision.*
to:
- project:
alias: occ
- job: [branch:*, pull-request]
+ job: [branch:*, pull-request:*]
- grant:
- secrets:get:repo:github.com/mozilla-releng/OpenCloudConfig:updatetooltoolrepo
- secrets:get:repo:github.com/mozilla-releng/OpenCloudConfig:updateworkertype
to:
- project:
alias: occ
job: [branch:alpha, branch:beta, branch:master]
@@ -1164,17 +1165,17 @@
environment: staging
# - mapper specific roles
- grant:
- secrets:get:project/releng/mapper/ci
to:
- projects:
alias: mapper
- job: [branch:*, pull-request]
+ job: [branch:*, pull-request:*]
- grant:
- secrets:get:project/releng/mapper/deploy
to:
- projects:
alias: mapper
job: [branch:dev, branch:staging, branch:production]
@@ -1209,32 +1210,32 @@
job: [branch:production, branch:dev]
# - tooltool specific roles
- grant:
- secrets:get:project/releng/tooltool/ci
to:
- projects:
alias: tooltool
- job: [branch:*, pull-request]
+ job: [branch:*, pull-request:*]
- grant:
- secrets:get:project/releng/tooltool/deploy
to:
- projects:
alias: tooltool
job: [branch:dev, branch:staging, branch:production]
# - treestatus specific roles
- grant:
- secrets:get:project/releng/treestatus/ci
to:
- projects:
alias: treestatus
- job: [branch:*, pull-request]
+ job: [branch:*, pull-request:*]
- grant:
- secrets:get:project/releng/treestatus/deploy
to:
- projects:
alias: treestatus
job: [branch:dev, branch:staging, branch:production]
@@ -1285,17 +1286,17 @@
- project:
feature: mobile-public-code-coverage
- grant:
- project:{trust_domain}:{trust_project}:releng:beetmover:action:push-to-maven
to:
- project:
feature: beetmover-maven-phase
- job: [release, pull-request, action:release-promotion]
+ job: [release, pull-request:*, action:release-promotion]
- project:
feature: beetmover-maven-nightly-phase
job: [cron:nightly]
- grant:
- project:{trust_domain}:{trust_project}:releng:beetmover:bucket:maven-production
to:
- project:
@@ -1308,33 +1309,33 @@
- project:{trust_domain}:{trust_project}:releng:beetmover:bucket:maven-nightly-staging
to:
- project:
feature: beetmover-maven-phase
level: 1
job: [release, action:release-promotion, cron:nightly]
- project:
feature: beetmover-maven-phase
- job: [pull-request]
+ job: [pull-request:*]
- grant:
- project:{trust_domain}:{trust_project}:releng:beetmover:bucket:maven-nightly-production
to:
- project:
feature: beetmover-maven-nightly-phase
level: 3
job: [cron:nightly]
- grant:
- project:{trust_domain}:{trust_project}:releng:beetmover:bucket:dep
- project:{trust_domain}:{trust_project}:releng:beetmover:action:direct-push-to-bucket
to:
- project:
feature: beetmover-phase
- job: [pull-request]
+ job: [pull-request:*]
- project:
feature: beetmover-phase
level: 1
job: [action:release-promotion]
- grant:
- project:{trust_domain}:{trust_project}:releng:beetmover:bucket:nightly
- project:{trust_domain}:{trust_project}:releng:beetmover:action:direct-push-to-bucket
@@ -1358,17 +1359,17 @@
level: 3
job: [release, action:release-promotion]
- grant:
- project:{trust_domain}:{trust_project}:releng:github:action:release
to:
- project:
feature: github-publication
- job: [action:release-promotion, release, pull-request]
+ job: [action:release-promotion, release, pull-request:*]
- grant:
- project:{trust_domain}:{trust_project}:releng:github:project:{trust_project}
to:
- project:
feature: github-publication
level: 3
job: [action:release-promotion, release]
@@ -1377,17 +1378,17 @@
- project:{trust_domain}:{trust_project}:releng:github:project:mock
to:
- project:
feature: github-publication
level: 1
job: [release, action:release-promotion]
- project:
feature: github-publication
- job: [pull-request]
+ job: [pull-request:*]
- grant:
- project:{trust_domain}:{trust_project}:releng:github:project:{alias}
to:
- project:
feature: github-publication
level: 1
job: [action:release-promotion, release]
@@ -1444,17 +1445,17 @@
alias: fenix
job: [cron:nightly-on-google-play]
- grant:
- project:mobile:{trust_project}:releng:googleplay:product:{trust_project}:dep
to:
- project:
feature: mobile-pushapk-phase
- job: [pull-request]
+ job: [pull-request:*]
- project:
feature: mobile-pushapk-phase
level: 1
job: [release, cron:*, action:release-promotion]
- grant:
- secrets:get:project/mobile/{trust_project}/firebase
to:
@@ -1465,26 +1466,26 @@
# Fenix PRs are restricted to collaborators, so exposing firebase is safe-enough for PRs.
# Fenix also has some Firebase tests on nightly.
alias: fenix
job:
- cron:nightly
- cron:nightly-on-google-play
- cron:screenshots
- cron:legacy-api-ui-tests
- - pull-request
+ - pull-request:trusted
- project:
# Focus PRs are restricted to collaborators, so exposing firebase is safe-enough for PRs.
# Focus also has some Firebase tests on nightly.
alias: focus-android
- job: [cron:nightly, pull-request]
+ job: [cron:nightly, pull-request:trusted]
- project:
# TODO - remove once focus/taskcluster work is complete
alias: staging-focus-android
- job: [pull-request]
+ job: [pull-request:trusted]
- grant:
- secrets:get:project/mobile/github
to:
- project:
feature: mobile-bump-github
level: 3
job: [cron:bump-*]
@@ -1494,17 +1495,17 @@
- queue:create-task:highest:proj-autophone/gecko-t-ap-perf-g5
- queue:create-task:highest:proj-autophone/gecko-t-ap-perf-p2
- queue:create-task:highest:proj-autophone/gecko-t-bitbar-gw-perf-g5
- queue:create-task:highest:proj-autophone/gecko-t-bitbar-gw-perf-p2
- queue:create-task:highest:proj-autophone/gecko-t-bitbar-gw-perf-a51
to:
- project:
feature: autophone
- job: [pull-request]
+ job: [pull-request:*]
- project:
alias: fenix
job: [cron:nightly, cron:nightly-test]
- project:
alias: reference-browser
job: [branch:*]
- grant:
@@ -1529,24 +1530,24 @@
- grant:
- queue:route:notify.email.android-components-team@mozilla.com.on-failed
- queue:route:notify.email.geckoview-core@mozilla.com.on-failed
to:
- project:
alias: android-components
# Used in order to warn the AC team whenever a GV update cannot be merged
- job: [pull-request]
+ job: [pull-request:*]
- grant:
- project:releng:ship-it:action:mark-as-shipped
to:
- project:
feature: shipit
- job: [release, pull-request]
+ job: [release, pull-request:*]
- project:
feature: [shipit, taskgraph-actions]
job: [action:release-promotion]
- grant:
- project:releng:ship-it:server:production
to:
- project:
@@ -1565,40 +1566,40 @@
- project:releng:ship-it:server:staging
to:
- project:
# TODO: once pull-request-based staging releases are more stable and
# available for all mobile projects, we can get rid of this `level=1`
# section which addresses the RelEngers forks
level: 1
feature: shipit
- job: [release, pull-request]
+ job: [release, pull-request:*]
- project:
level: 1
feature: [shipit, taskgraph-actions]
job: [action:release-promotion]
- project:
level: 3
feature: [shipit, taskgraph-actions]
- job: [pull-request]
+ job: [pull-request:*]
# fenix specific scopes
- grant:
- queue:route:index.project.fenix.android.preview-builds
- github:create-comment:mozilla-mobile/fenix
to:
- project:
alias: fenix
- job: [pull-request]
+ job: [pull-request:*]
- grant:
- secrets:get:project/mobile/fenix/public-tokens
to:
- project:
alias: fenix
- job: [branch:*, pull-request]
+ job: [branch:*, pull-request:trusted]
- grant:
- secrets:get:project/mobile/fenix/nightly-simulation
to:
- project:
alias: fenix
job: [branch:*, cron:nightly-test]
@@ -1670,24 +1671,24 @@
# focus (android) scopes
- grant:
- queue:scheduler-id:taskcluster-github
- queue:route:statuses
to:
- project:
alias: focus-android
- job: [branch:*, cron:*, pull-request, release]
+ job: [branch:*, cron:*, pull-request:*, release]
- grant:
- queue:route:notify.irc-channel.#android-ci.on-any
to:
- project:
alias: focus-android
- job: [branch:*, pull-request]
+ job: [branch:*, pull-request:*]
- grant:
- secrets:get:project/mobile/focus-android/nightly
- secrets:get:project/mobile/focus-android/beta
- secrets:get:project/mobile/focus-android/release
to:
- project:
alias: focus-android
@@ -1719,17 +1720,17 @@
# firefox-tv specific scopes
- grant:
- secrets:get:project/mobile/firefox-tv/tokens
- queue:route:index.project.{trust_domain}.{alias}.cache.level-{level}.*
to:
- project:
alias: firefox-tv
- job: [branch:*, pull-request, release]
+ job: [branch:*, pull-request:*, release]
- grant:
- queue:route:notify.email.firefox-tv@mozilla.com.on-completed
- project:mobile:firefox-tv:releng:signing:cert:production-signing
to:
- project:
alias: firefox-tv
job: [release]
@@ -1762,17 +1763,17 @@
- queue:create-task:highest:l10n-{level}/*
- queue:create-task:{priority}:built-in/*
- queue:route:index.{trust_domain}.{alias}.cache.level-{level}.*
- queue:route:notify.email.*
to:
- project:
alias:
- android-l10n-tooling
- job: [pull-request, branch:*, cron:*]
+ job: [pull-request:*, branch:*, cron:*]
- grant:
- secrets:get:l10n/level-{level}/*
to:
- project:
alias:
- android-l10n-tooling
job: [branch:*, cron:*]
@@ -1785,17 +1786,17 @@
- queue:scheduler-id:{trust_domain}-level-{level}
- docker-worker:cache:{trust_domain}-level-{level}-*
- generic-worker:cache:{trust_domain}-level-{level}-*
- queue:route:notify.email.*
to:
- project:
alias:
- elmo-taskcluster
- job: [pull-request, branch:*, cron:*]
+ job: [pull-request:*, branch:*, cron:*]
- grant:
- secrets:get:l10n/level-{level}/*
to:
- project:
alias:
- elmo-taskcluster
job: [branch:*, cron:*]
@@ -1824,17 +1825,17 @@
- generic-worker:cache:{trust_domain}-level-1-*
to:
- project:
alias:
- mozilla-vpn-client
job:
- branch:*
- cron:*
- - pull-request
+ - pull-request:*
- release
- grant:
- project:mozillavpn:releng:beetmover:action:push-to-candidates
- project:mozillavpn:releng:beetmover:bucket:release
to:
- project:
alias:
@@ -1859,26 +1860,31 @@
- project:mozillavpn:releng:beetmover:bucket:dep
- project:mozillavpn:releng:signing:cert:dep-signing
to:
- project:
alias:
- mozilla-vpn-client
job:
- branch:*
- - pull-request
+ - pull-request:*
- release
- grant:
- project:{trust_project}:releng:signing:format:*
- project:releng:services/tooltool/api/download/public
- project:releng:services/tooltool/api/download/internal
to:
- project:
alias: mozilla-vpn-client
+ job:
+ - action:*
+ - branch:*
+ - pull-request:trusted
+ - release
- grant:
- project:mozillavpn:releng:googleplay:product:mozillavpn
- queue:route:index.{trust_domain}.v2.mozilla-vpn-client.release.*
to:
- project:
alias:
- mozilla-vpn-client
@@ -1935,17 +1941,17 @@
- project:releng:services/tooltool/api/download/public
- project:releng:services/tooltool/api/download/internal
to:
- project:
alias:
- staging-mozilla-vpn-client
job:
- branch:*
- - pull-request
+ - pull-request:trusted
- release
- action:release-promotion
- grant:
- secrets:get:project/mozillavpn/tokens
to:
- project:
alias:
@@ -2023,17 +2029,17 @@
- queue:scheduler-id:xpi-level-1
- docker-worker:cache:xpi-level-1-*
- secrets:get:project/xpi/xpi-github-clone-ssh
- project:xpi:releng:signing:cert:dep-signing
- queue:create-task:low:scriptworker-k8s/xpi-t-*
to:
- project:
feature: xpi-roles
- job: [pull-request, branch:*, cron:*, action:*, tag:*]
+ job: [pull-request:*, branch:*, cron:*, action:*, tag:*]
- roles:
# The mozilla-extensions github organization is designed to allow for
#
# easily creating new repos for xpi source. Let's automatically
# give them level 1 scopes for master, PRs, and other branches.
- repo:github.com/mozilla-extensions/*
- repo:github.com/mozilla-releng/staging-xpi-*
@@ -2067,17 +2073,17 @@
- queue:route:index.{trust_domain}.v2.{alias}.*
- queue:route:index.{trust_domain}.v2.staging-adhoc-manifest.*
- queue:route:index.adhoc-signing.cache.level-{level}.*
- queue:get-artifact:releng/adhoc/*
- queue:route:notify.email.*
to:
- project:
feature: adhoc-roles
- job: [branch:*, action:*, pull-request, action:*, cron:*]
+ job: [branch:*, action:*, pull-request:trusted, action:*, cron:*]
- grant:
- project:adhoc:releng:signing:cert:release-signing
- project:adhoc:releng:signing:cert:nightly-signing
- project:adhoc:releng:ship-it:server:production
- queue:route:index.{trust_domain}.v2.adhoc-manifest.*
to:
- project:
@@ -2097,17 +2103,17 @@
# explicitly grant level 1 scopes for PRs
- queue:scheduler-id:scriptworker-level-1
- queue:create-task:highest:scriptworker-1/*
- queue:route:index.scriptworker.cache.level-1.*
to:
- project:
alias:
- scriptworker-scripts
- job: [branch:*, action:*, pull-request, action:*, cron:*]
+ job: [branch:*, action:*, pull-request:*, action:*, cron:*]
# - scriptworker-scripts specific roles
# XXX delete these once we port scriptworker-scripts cloudops deploys to CoT
# downloads
- grant:
- secrets:get:project/releng/scriptworker-scripts/deploy
to:
- projects:
--- a/projects.yml
+++ b/projects.yml
@@ -36,16 +36,17 @@
# - `beetmover-maven-nightly-phase` -- this https://github.com/mozilla-mobile repository should have beetmover nightly production related scopes associated
# - `mobile-firebase-testing` -- this https://github.com/mozilla-mobile repository has end-to-end testing involving devices hosted at Google's Firebase
# - `mobile-bump-github` -- this https://github.com/mozilla-mobile repository gets bumped.
# - `mobile-public-code-coverage` -- this https://github.com/mozilla-mobile repository has code coverage enabled on PRs
# - `mobile-sign-phase` -- this https://github.com/mozilla-mobile repository should have sign related scopes associated
# - `mobile-pushapk-phase` -- this https://github.com/mozilla-mobile repository should have pushapk related scopes associated
# - `github-taskgraph` -- this github repository has started using taskgraph
# - `github-publication` -- this github repository automates publication to github releases
+# - `github-pull-request` -- this github repository uses github pull requests; Value should include a 'policy' matching the repo's `pullRequestPolicy`
# - `gecko-actions` -- this repository should have gecko-related action hooks defined
# - 'scriptworker' -- this repository uses at least one scriptworker instance
# - 'shipit' -- this repository interacts with a shipit instance
# - 'taskgraph-cron' -- tasks defined in `.cron.yml` can run for this project (non-gecko/comm taskgraph repos only)
# - 'taskgraph-actions' -- this repository defines in-tree actions and should have corresponding hooks defined
# - `trust-domain-scopes` -- this repository should have generic scopes associated to its trust domain
# - `treeherder-reporting` -- this repository reports results to treeherder
# - `autophone` -- this repository is allowed to use the Android farm called "Autophone"
@@ -460,16 +461,18 @@ ci-configuration-try:
taskgraph:
repo: https://github.com/taskcluster/taskgraph
repo_type: git
trust_domain: taskgraph
default_branch: main
level: 3
features:
github-taskgraph: true
+ github-pull-request:
+ policy: collaborators
taskgraph-actions: true
trust-domain-scopes: true
treeherder-reporting: true
version-control-tools:
repo: https://hg.mozilla.org/hgcustom/version-control-tools
repo_type: hg
access: scm_versioncontrol
@@ -484,16 +487,18 @@ firefox-android:
repo_type: git
default_branch: main
level: 3
features:
beetmover-maven-phase: true
beetmover-maven-nightly-phase: true
github-publication: true
github-taskgraph: true
+ github-pull-request:
+ policy: public
mobile-roles: true
mobile-firebase-testing: true
mobile-public-code-coverage: true
mobile-sign-phase: true
scriptworker: true
shipit: true
taskgraph-actions: true
taskgraph-cron: true
@@ -508,16 +513,18 @@ staging-firefox-android:
trust_project: firefox-android
repo_type: git
default_branch: main
level: 1
features:
beetmover-maven-phase: true
beetmover-maven-nightly-phase: true
github-publication: true
+ github-pull-request:
+ policy: public
github-taskgraph: true
mobile-roles: true
mobile-firebase-testing: true
mobile-public-code-coverage: true
mobile-sign-phase: true
scriptworker: true
shipit: true
taskgraph-actions: true
@@ -536,16 +543,18 @@ android-components:
repo_type: git
default_branch: main
level: 3
features:
beetmover-maven-phase: true
beetmover-maven-nightly-phase: true
github-publication: true
github-taskgraph: true
+ github-pull-request:
+ policy: public
mobile-roles: true
mobile-firebase-testing: true
mobile-public-code-coverage: true
mobile-sign-phase: true
scriptworker: true
shipit: true
taskgraph-actions: true
taskgraph-cron: true
@@ -561,16 +570,18 @@ staging-android-components:
repo_type: git
default_branch: main
level: 1
features:
beetmover-maven-phase: true
beetmover-maven-nightly-phase: true
github-publication: true
github-taskgraph: true
+ github-pull-request:
+ policy: public
mobile-roles: true
mobile-firebase-testing: true
mobile-public-code-coverage: true
mobile-sign-phase: true
scriptworker: true
shipit: true
taskgraph-actions: true
taskgraph-cron: true
@@ -585,16 +596,18 @@ reference-browser:
trust_domain: mobile
trust_project: reference-browser
repo_type: git
default_branch: master
level: 3
features:
autophone: true
github-taskgraph: true
+ github-pull-request:
+ policy: public
mobile-roles: true
mobile-bump-github: true
mobile-firebase-testing: true
mobile-sign-phase: true
mobile-pushapk-phase: true
scriptworker: true
taskgraph-actions: true
taskgraph-cron: true
@@ -613,16 +626,18 @@ fenix:
trust_project: fenix
repo_type: git
default_branch: main
level: 3
features:
autophone: true
beetmover-phase: true
github-taskgraph: true
+ github-pull-request:
+ policy: collaborators
github-publication: true
mobile-roles: true
mobile-bump-github: true
mobile-firebase-testing: true
mobile-public-code-coverage: true
mobile-pushapk-phase: true
mobile-sign-phase: true
scriptworker: true
@@ -645,16 +660,18 @@ staging-fenix:
repo_type: git
default_branch: main
level: 1
features:
autophone: true
beetmover-phase: true
github-publication: true
github-taskgraph: true
+ github-pull-request:
+ policy: collaborators
mobile-roles: true
mobile-firebase-testing: true
mobile-public-code-coverage: true
mobile-pushapk-phase: true
mobile-sign-phase: true
scriptworker: true
shipit: true
taskgraph-actions: true
@@ -671,16 +688,18 @@ focus-android:
trust_domain: mobile
trust_project: focus-android
repo_type: git
default_branch: main
level: 3
features:
beetmover-phase: true
github-taskgraph: true
+ github-pull-request:
+ policy: collaborators
github-publication: true
mobile-roles: true
mobile-bump-github: true
mobile-firebase-testing: true
mobile-public-code-coverage: true
mobile-pushapk-phase: true
mobile-sign-phase: true
scriptworker: true
@@ -698,16 +717,18 @@ staging-focus-android:
trust_domain: mobile
trust_project: focus-android
repo_type: git
default_branch: main
level: 1
features:
github-publication: true
github-taskgraph: true
+ github-pull-request:
+ policy: collaborators
mobile-roles: true
mobile-firebase-testing: true
mobile-public-code-coverage: true
mobile-pushapk-phase: true
mobile-sign-phase: true
scriptworker: true
shipit: true
taskgraph-actions: true
@@ -722,32 +743,36 @@ staging-focus-android:
firefox-ios:
repo: https://github.com/mozilla-mobile/firefox-ios
trust_domain: mobile
trust_project: firefox-ios
repo_type: git
level: 3
features:
github-taskgraph: true
+ github-pull-request:
+ policy: public
mobile-roles: true
taskgraph-actions: true
taskgraph-cron: true
treeherder-reporting: true
trust-domain-scopes: true
cron:
targets: [l10-screenshots]
focus-ios:
repo: https://github.com/mozilla-mobile/focus-ios
trust_domain: mobile
trust_project: focus-ios
repo_type: git
level: 3
features:
github-taskgraph: true
+ github-pull-request:
+ policy: public
mobile-roles: true
taskgraph-actions: true
taskgraph-cron: true
treeherder-reporting: true
trust-domain-scopes: true
cron:
targets: [l10-screenshots]
@@ -757,161 +782,212 @@ application-services:
repo_type: git
level: 3
trust_domain: app-services
trust_project: app-services
features:
# TODO Bug 1601687 - Enable `beetmover-maven-phase` once scriptworker scopes are predictible
# across projects.
github-taskgraph: true
+ github-pull-request:
+ policy: public
scriptworker: true
taskgraph-cron: true
taskgraph-actions: true
glean:
repo: https://github.com/mozilla/glean
repo_type: git
level: 3
trust_domain: glean
trust_project: glean
default_branch: main
features:
# TODO Bug 1601687 - Enable `beetmover-maven-phase` once scriptworker scopes are predictible
# across projects.
github-taskgraph: true
+ github-pull-request:
+ policy: public
scriptworker: true
taskgraph-actions: true
# mozilla-releng Github repositories
k8s-autoscale:
repo: https://github.com/mozilla-releng/k8s-autoscale
repo_type: git
default_branch: master
trust_domain: releng
level: 3
+ features:
+ github-pull-request:
+ policy: public
mapper:
repo: https://github.com/mozilla-releng/mapper
repo_type: git
default_branch: master
trust_domain: releng
level: 3
+ features:
+ github-pull-request:
+ policy: public
product-details:
repo: https://github.com/mozilla-releng/product-details
repo_type: git
trust_domain: releng
level: 3
+ features:
+ github-pull-request:
+ policy: collaborators
shipit:
repo: https://github.com/mozilla-releng/shipit
repo_type: git
features:
github-taskgraph: true
+ github-pull-request:
+ policy: public
trust-domain-scopes: true
trust_domain: releng
level: 3
tooltool:
repo: https://github.com/mozilla-releng/tooltool
repo_type: git
default_branch: master
trust_domain: releng
level: 3
+ features:
+ github-pull-request:
+ policy: public
treestatus:
repo: https://github.com/mozilla-releng/treestatus
repo_type: git
default_branch: master
trust_domain: releng
level: 3
+ features:
+ github-pull-request:
+ policy: public
balrog:
repo: https://github.com/mozilla-releng/balrog
repo_type: git
trust_domain: releng
level: 3
+ features:
+ github-pull-request:
+ policy: public
taskhuddler:
repo: https://github.com/mozilla-releng/taskhuddler
repo_type: git
default_branch: master
trust_domain: releng
level: 3
+ features:
+ github-pull-request:
+ policy: public
scriptworker:
repo: https://github.com/mozilla-releng/scriptworker
repo_type: git
default_branch: main
trust_domain: scriptworker
level: 3
features:
trust-domain-scopes: true
taskgraph-actions: true
github-taskgraph: true
+ github-pull-request:
+ policy: collaborators
-# mozilla-releng Github repositories
build-puppet:
repo: https://github.com/mozilla-releng/build-puppet
repo_type: git
default_branch: master
trust_domain: releng
level: 1
+ features:
+ github-pull-request:
+ policy: public
occ:
repo: https://github.com/mozilla-releng/OpenCloudConfig
repo_type: git
default_branch: master
trust_domain: releng
level: 3
+ features:
+ github-pull-request:
+ policy: public
winsign:
repo: https://github.com/mozilla-releng/winsign
repo_type: git
default_branch: main
trust_domain: releng
level: 1
+ features:
+ github-pull-request:
+ policy: public
mozilla-version:
repo: https://github.com/mozilla-releng/mozilla-version
repo_type: git
default_branch: main
trust_domain: releng
level: 1
+ features:
+ github-pull-request:
+ policy: public
build-mar:
repo: https://github.com/mozilla-releng/build-mar
repo_type: git
default_branch: master
trust_domain: releng
level: 1
+ features:
+ github-pull-request:
+ policy: public
cloud-image-builder:
repo: https://github.com/mozilla-platform-ops/cloud-image-builder
repo_type: git
default_branch: main
trust_domain: relops
level: 3
+ features:
+ github-pull-request:
+ policy: collaborators
cloud-image-deploy:
repo: https://github.com/mozilla-platform-ops/cloud-image-deploy
repo_type: git
default_branch: main
trust_domain: relops
level: 3
+ features:
+ github-pull-request:
+ policy: collaborators
# L10n repositories
android-l10n-tooling:
repo: https://github.com/mozilla-l10n/android-l10n-tooling
repo_type: git
default_branch: master
level: 3
trust_domain: l10n
features:
github-taskgraph: true
+ github-pull-request:
+ policy: public
taskgraph-cron: true
taskgraph-actions: true
cron:
targets:
- target: update-l10n
bindings:
- exchange: exchange/taskcluster-github/v1/push
routing_key_pattern: primary.mozilla-mobile.fenix
@@ -927,142 +1003,166 @@ mozilla-vpn-client:
repo: https://github.com/mozilla-mobile/mozilla-vpn-client
repo_type: git
default_branch: main
level: 3
trust_domain: mozillavpn
trust_project: mozillavpn
features:
github-taskgraph: true
+ github-pull-request:
+ policy: collaborators
taskgraph-actions: true
# Enable this after .taskcluster.yml and .cron.yml exist in the repo
# taskgraph-cron: true
treeherder-reporting: true
trust-domain-scopes: true
staging-mozilla-vpn-client:
repo: https://github.com/mozilla-releng/staging-mozilla-vpn-client
repo_type: git
default_branch: main
level: 1
trust_domain: mozillavpn
trust_project: mozillavpn
features:
github-taskgraph: true
+ github-pull-request:
+ policy: collaborators
taskgraph-actions: true
# Enable this after .taskcluster.yml and .cron.yml exist in the repo
# taskgraph-cron: true
treeherder-reporting: true
trust-domain-scopes: true
# Bug 1520281: Add user repositories for experimenting with taskgraph and mobile
# repo:github.com/mozilla-extensions/* is configured in grants.yml, under the xpi-roles feature
xpi-manifest:
repo: https://github.com/mozilla-extensions/xpi-manifest
repo_type: git
default_branch: main
trust_domain: xpi
level: 3
features:
+ github-pull-request:
+ policy: collaborators
trust-domain-scopes: true
xpi-roles: true
taskgraph-actions: true
taskgraph-cron: true
rally-core-addon:
repo: https://github.com/mozilla-rally/rally-core-addon
repo_type: git
default_branch: master
trust_domain: xpi
level: 1
features:
+ github-pull-request:
+ policy: collaborators
trust-domain-scopes: true
taskgraph-actions: true
xpi-roles: true
staging-xpi-manifest:
repo: https://github.com/mozilla-releng/staging-xpi-manifest
repo_type: git
default_branch: main
trust_domain: xpi
level: 1
features:
+ github-pull-request:
+ policy: collaborators
trust-domain-scopes: true
xpi-roles: true
taskgraph-actions: true
taskgraph-cron: true
staging-xpi-public:
repo: https://github.com/mozilla-releng/staging-xpi-public
repo_type: git
default_branch: main
trust_domain: xpi
level: 1
features:
+ github-pull-request:
+ policy: public
trust-domain-scopes: true
xpi-roles: true
staging-xpi-private:
repo: https://github.com/mozilla-releng/staging-xpi-private
repo_type: git
default_branch: master
trust_domain: xpi
level: 1
features:
+ github-pull-request:
+ policy: collaborators
trust-domain-scopes: true
xpi-roles: true
# Bug 1594621: Create an adhoc signing repository
staging-adhoc-signing:
repo: https://github.com/mozilla-releng/staging-adhoc-signing
repo_type: git
default_branch: master
trust_domain: adhoc
level: 1
features:
trust-domain-scopes: true
adhoc-roles: true
taskgraph-actions: true
github-taskgraph: true
+ github-pull-request:
+ policy: collaborators
adhoc-signing:
repo: https://github.com/mozilla-releng/adhoc-signing
repo_type: git
default_branch: main
trust_domain: adhoc
level: 3
features:
trust-domain-scopes: true
adhoc-roles: true
taskgraph-actions: true
github-taskgraph: true
+ github-pull-request:
+ policy: collaborators
# Bug 1614312: Add code-analysis project for code-review & code-coverage
code-review:
repo: https://github.com/mozilla/code-review
repo_type: git
default_branch: master
trust_domain: code-analysis
level: 3
features:
trust-domain-scopes: true
+ github-pull-request:
+ policy: public
# Bug 1597598: Add taskgraph support to scriptworker-scripts
scriptworker-scripts:
repo: https://github.com/mozilla-releng/scriptworker-scripts
repo_type: git
default_branch: master
trust_domain: scriptworker
level: 3
features:
trust-domain-scopes: true
taskgraph-actions: true
github-taskgraph: true
+ github-pull-request:
+ policy: public
# Bug 1617635: Support building & indexing code-coverage docker image
code-coverage:
repo: https://github.com/mozilla/code-coverage
repo_type: git
default_branch: master
trust_domain: code-analysis
level: 3
features:
trust-domain-scopes: true
+ github-pull-request:
+ policy: public
new file mode 100644
--- /dev/null
+++ b/src/ciadmin/check/check_pull_request_policies.py
@@ -0,0 +1,54 @@
+# This Source Code Form is subject to the terms of the Mozilla Public License,
+# v. 2.0. If a copy of the MPL was not distributed with this file, You can
+# obtain one at http://mozilla.org/MPL/2.0/.
+
+import pytest
+import yaml
+from tcadmin.util.sessions import with_aiohttp_session
+
+from ciadmin.generate import tcyml
+from ciadmin.generate.ciconfig.projects import Project
+
+
+async def _get_pull_request_policy(project):
+ config = yaml.safe_load(
+ await tcyml.get(
+ project.repo,
+ repo_type=project.repo_type,
+ revision=None,
+ default_branch=project.default_branch,
+ )
+ )
+ return config.get("policy", {}).get("pullRequests")
+
+
+@pytest.mark.asyncio
+@with_aiohttp_session
+async def check_pull_request_policies_for_git_repos():
+ """Ensures that the pull-request policy defined in projects.yml
+ matches the one in-repo.
+ """
+ tcyml_v0_projects = {"build-puppet", "occ"}
+
+ projects = await Project.fetch_all()
+
+ def filter_project(p):
+ # TODO: find a better flag to filter out private repos
+ return (
+ p.repo_type == "git"
+ and "private" not in p.repo
+ and p.feature("github-pull-request")
+ and p.alias not in tcyml_v0_projects
+ )
+
+ pr_policies = {
+ project.alias: project.feature("github-pull-request", key="policy")
+ for project in projects
+ if filter_project(project)
+ }
+ github_pr_policies = {
+ project.alias: await _get_pull_request_policy(project)
+ for project in projects
+ if filter_project(project)
+ }
+ assert pr_policies == github_pr_policies
--- a/src/ciadmin/generate/ciconfig/projects.py
+++ b/src/ciadmin/generate/ciconfig/projects.py
@@ -111,16 +111,25 @@ class Project:
"its `level` value".format(self.alias)
)
if self.access:
raise ValueError(
"Non-hg repo {} cannot define an `access` "
"property".format(self.alias)
)
+ # Convert boolean features into a dict of the form {"enabled": <val>}
+ for name, val in self.features.items():
+ if isinstance(val, dict):
+ val.setdefault("enabled", True)
+ elif isinstance(val, bool):
+ self.features[name] = {"enabled": val}
+ else:
+ raise ValueError("Feature {} must be a dict or boolean".format(name))
+
@staticmethod
async def fetch_all():
"""Load project metadata from projects.yml in ci-configuration"""
projects = await get_ciconfig_file("projects.yml")
return [Project(alias, **info) for alias, info in projects.items()]
@staticmethod
async def get(alias):
@@ -131,24 +140,24 @@ class Project:
return project
else:
raise KeyError("Project {} is not defined".format(alias))
# The `features` property is designed for ease of use in yaml, with true and false
# values for each feature; the `feature()` and `enabled_features` attributes provide
# easier access for Python uses.
- def feature(self, feature):
+ def feature(self, feature, key="enabled"):
"Return True if this feature is enabled"
- return feature in self.features and self.features[feature]
+ return feature in self.features and self.features[feature][key]
@property
def enabled_features(self):
"The list of enabled features"
- return [f for f, enabled in self.features.items() if enabled]
+ return [f for f, val in self.features.items() if val["enabled"]]
def get_level(self):
"Get the level, or None if the access level does not define a level"
if self.access and self.access.startswith("scm_level_"):
return int(self.access[-1])
elif self.access and self.access in SYMBOLIC_GROUP_LEVELS:
return SYMBOLIC_GROUP_LEVELS[self.access]
elif self._level:
--- a/src/ciadmin/generate/grants.py
+++ b/src/ciadmin/generate/grants.py
@@ -49,52 +49,91 @@ def add_scopes_for_projects(grant, grant
continue
if grantee.is_try is not None:
if project.is_try != grantee.is_try:
continue
if not match(grantee.trust_domain, project.trust_domain):
continue
jobs = grantee.job
+
+ # Force being explicit with pull-request policies. Otherwise, the `pull-request`
+ # job would be equivalent to `pull-request:trusted`, which may not be intended.
+ if "pull-request" in jobs:
+ raise RuntimeError(
+ "Invalid job 'pull-request'! Use 'pull-request:*' instead."
+ )
+
+ pr_policy = (project.feature("github-pull-request", key="policy") or "").strip()
+
if "*" in jobs and project.repo_type == "git" and project.level != 1:
# Github mixes pull-requests and other tasks under the same prefix
# Since pull-requests should be level-1, we need to explicitly
# split based on the job
jobs = [job for job in jobs if job != "*"]
- jobs += ["pull-request", "branch:*", "release", "cron:*", "action:*"]
+ jobs += ["pull-request:*", "branch:*", "release", "cron:*", "action:*"]
# Only grant scopes to `cron:` or `action:` jobs if the corresponding features
# are enabled. This allows having generic grants that don't generate unused
# roles
if not project.feature("taskgraph-cron") and not project.feature("gecko-cron"):
jobs = [job for job in jobs if not job.startswith("cron:")]
if not project.feature("taskgraph-actions") and not project.feature(
"gecko-actions"
):
jobs = [job for job in jobs if not job.startswith("action:")]
- if project.repo_type != "git" or not grantee.include_pull_requests:
- jobs = [job for job in jobs if job != "pull-request"]
+
+ # Only grant pull-request scopes where it makes sense.
+ if (
+ project.repo_type != "git"
+ or not pr_policy
+ or not grantee.include_pull_requests
+ ):
+ jobs = [job for job in jobs if not job.startswith("pull-request")]
+
+ if "pull-request:*" in jobs:
+ jobs.remove("pull-request:*")
+ jobs.extend(["pull-request:trusted", "pull-request:untrusted"])
+
+ # Remove any 'pull-request:trusted' jobs for projects using the 'public' policy.
+ # Similarly, remove any 'pull-request:untrusted' jobs for projects using the
+ # 'collaborators' policy. Only the 'public_restricted' policy supports both at
+ # the same time.
+ if pr_policy == "public":
+ jobs = [job for job in jobs if job != "pull-request:trusted"]
+ elif pr_policy.startswith("collaborators"):
+ jobs = [job for job in jobs if job != "pull-request:untrusted"]
+
+ def job_to_role_suffix(job):
+ # Normalize any `pull-request:` jobs to their appropriate role
+ # suffix.
+ if job == "pull-request:untrusted" and pr_policy == "public_restricted":
+ return "pull-request-untrusted"
+ elif job.startswith("pull-request"):
+ return "pull-request"
+ return job
# ok, this project matches!
for job in jobs:
- roleId = "{}:{}".format(project.role_prefix, job)
+ suffix = job_to_role_suffix(job)
+ roleId = "{}:{}".format(project.role_prefix, suffix)
# perform substitutions as grants.yml describes
subs = {}
subs["alias"] = project.alias
if project.trust_domain:
subs["trust_domain"] = project.trust_domain
if project.trust_project:
subs["trust_project"] = project.trust_project
level = project.get_level()
if level is not None:
subs["level"] = project.level
# In order to avoid granting pull-requests graphs
# access to the level-3 workers, we overwrite their value here
- if job == "pull-request":
+ if job.startswith("pull-request"):
subs["level"] = 1
subs["priority"] = LEVEL_PRIORITIES[project.level]
try:
subs["repo_path"] = project.repo_path
except AttributeError:
pass # not an known supported repo..
for scope in grant.scopes:
--- a/tests/ciadmin/test_generate_ciconfig_projects.py
+++ b/tests/ciadmin/test_generate_ciconfig_projects.py
@@ -99,17 +99,20 @@ async def test_fetch_defaults(
{
"access": "scm_level_2",
"cron": {
"email_when_trigger_failure": True,
"notify_emails": [],
"targets": ["a", "b"],
},
"default_branch": "default",
- "features": {"hg-push": True, "gecko-cron": False},
+ "features": {
+ "hg-push": {"enabled": True},
+ "gecko-cron": {"enabled": False},
+ },
"is_try": True,
"parent_repo": "https://hg.mozilla.org/mozilla-unified",
"repo_type": "hg",
"repo": "https://hg.mozilla.org/projects/ash",
"trust_domain": "gecko",
"trust_project": None,
},
{
@@ -120,17 +123,20 @@ async def test_fetch_defaults(
"email_when_trigger_failure": True,
"notify_emails": [],
"targets": [
{"target": "a", "bindings": []},
{"target": "b", "bindings": []},
],
},
"default_branch": "default",
- "features": {"hg-push": True, "gecko-cron": False},
+ "features": {
+ "hg-push": {"enabled": True},
+ "gecko-cron": {"enabled": False},
+ },
"is_try": True,
"parent_repo": "https://hg.mozilla.org/mozilla-unified",
"repo": "https://hg.mozilla.org/projects/ash",
"repo_path": "projects/ash",
"repo_type": "hg",
"role_prefix": "repo:hg.mozilla.org/projects/ash",
"taskcluster_yml_project": None,
"trust_domain": "gecko",
@@ -141,17 +147,20 @@ async def test_fetch_defaults(
"beetmoverscript", # git project but not mobile
{
"cron": {
"email_when_trigger_failure": True,
"notify_emails": [],
"targets": ["a", "b"],
},
"default_branch": "main",
- "features": {"hg-push": True, "gecko-cron": False},
+ "features": {
+ "hg-push": {"enabled": True},
+ "gecko-cron": {"enabled": False},
+ },
"is_try": False,
"level": 3,
"parent_repo": "https://github.com/mozilla-releng/",
"repo_type": "git",
"repo": "https://github.com/mozilla-releng/beetmoverscript/",
"trust_domain": "beet",
"trust_project": None,
},
@@ -163,17 +172,20 @@ async def test_fetch_defaults(
"email_when_trigger_failure": True,
"notify_emails": [],
"targets": [
{"target": "a", "bindings": []},
{"target": "b", "bindings": []},
],
},
"default_branch": "main",
- "features": {"hg-push": True, "gecko-cron": False},
+ "features": {
+ "hg-push": {"enabled": True},
+ "gecko-cron": {"enabled": False},
+ },
"is_try": False,
"parent_repo": "https://github.com/mozilla-releng/",
"repo": "https://github.com/mozilla-releng/beetmoverscript/",
"repo_path": "mozilla-releng/beetmoverscript",
"repo_type": "git",
"role_prefix": "repo:github.com/mozilla-releng/beetmoverscript",
"taskcluster_yml_project": None,
"trust_domain": "beet",
@@ -197,19 +209,25 @@ async def test_fetch_nodefaults(
def test_project_feature():
"Test the feature method"
prj = Project(
alias="prj",
repo="https://hg.mozilla.org/prj",
repo_type="hg",
access="scm_level_3",
trust_domain="gecko",
- features={"taskcluster-pull": True, "gecko-cron": False},
+ features={
+ "taskcluster-pull": True,
+ "gecko-cron": False,
+ "some-data": {"foo": "bar"},
+ },
)
assert prj.feature("taskcluster-pull")
+ assert prj.feature("some-data")
+ assert prj.feature("some-data", key="foo") == "bar"
assert not prj.feature("gecko-cron")
assert not prj.feature("gecko-cron")
assert not prj.feature("buildbot")
def test_project_enabled_features():
"Test enabled_features"
prj = Project(
--- a/tests/ciadmin/test_generate_grants.py
+++ b/tests/ciadmin/test_generate_grants.py
@@ -1,14 +1,16 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public License,
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
# obtain one at http://mozilla.org/MPL/2.0/.
+from pprint import pprint
+
import pytest
from tcadmin.resources import Resources
from ciadmin.generate import grants
from ciadmin.generate.ciconfig.grants import Grant, GroupGrantee, ProjectGrantee
from ciadmin.generate.ciconfig.projects import Project
@@ -229,16 +231,146 @@ class TestAddScopesForGroups:
"{..} in scopes is an error for groups"
grantee = GroupGrantee(groups=["group1", "group2"])
with pytest.raises(KeyError):
grants.add_scopes_for_groups(
Grant(scopes=["level:{level}"], grantees=[grantee]), grantee, add_scope
)
+class TestAddScopesForGithubPullRequest:
+
+ projects = [
+ Project(
+ alias="hg",
+ repo="https://hg.mozilla.org/hg",
+ repo_type="hg",
+ access="scm_level_1",
+ trust_domain="foo",
+ ),
+ Project(
+ alias="no-prs",
+ repo="https://github.com/mozilla/no-prs",
+ repo_type="git",
+ level=3,
+ trust_domain="foo",
+ ),
+ Project(
+ alias="public",
+ repo="https://github.com/mozilla/public",
+ repo_type="git",
+ level=3,
+ trust_domain="foo",
+ features={
+ "github-pull-request": {
+ "enabled": True,
+ "policy": "public",
+ }
+ },
+ ),
+ Project(
+ alias="public-restricted",
+ repo="https://github.com/mozilla/public-restricted",
+ repo_type="git",
+ level=3,
+ trust_domain="foo",
+ features={
+ "github-pull-request": {
+ "enabled": True,
+ "policy": "public_restricted",
+ }
+ },
+ ),
+ Project(
+ alias="collaborators",
+ repo="https://github.com/mozilla/collaborators",
+ repo_type="git",
+ level=3,
+ trust_domain="foo",
+ features={
+ "github-pull-request": {
+ "enabled": True,
+ "policy": "collaborators",
+ }
+ },
+ ),
+ ]
+
+ def test_grant_to_pull_request_trusted(self, add_scope):
+ grantee = ProjectGrantee(job=["pull-request:trusted"])
+ grants.add_scopes_for_projects(
+ Grant(scopes=["sc"], grantees=[grantee]), grantee, add_scope, self.projects
+ )
+ # Dump expected for copy/paste.
+ pprint(add_scope.added)
+ assert add_scope.added == [
+ ("repo:github.com/mozilla/public-restricted:pull-request", "sc"),
+ ("repo:github.com/mozilla/collaborators:pull-request", "sc"),
+ ]
+
+ def test_grant_to_pull_request_untrusted(self, add_scope):
+ grantee = ProjectGrantee(job=["pull-request:untrusted"])
+ grants.add_scopes_for_projects(
+ Grant(scopes=["sc"], grantees=[grantee]), grantee, add_scope, self.projects
+ )
+ # Dump expected for copy/paste.
+ pprint(add_scope.added)
+ assert add_scope.added == [
+ ("repo:github.com/mozilla/public:pull-request", "sc"),
+ ("repo:github.com/mozilla/public-restricted:pull-request-untrusted", "sc"),
+ ]
+
+ def test_grant_to_pull_request_star(self, add_scope):
+ grantee = ProjectGrantee(job=["pull-request:*"])
+ grants.add_scopes_for_projects(
+ Grant(scopes=["sc"], grantees=[grantee]), grantee, add_scope, self.projects
+ )
+ # Dump expected for copy/paste.
+ pprint(add_scope.added)
+ assert add_scope.added == [
+ ("repo:github.com/mozilla/public:pull-request", "sc"),
+ ("repo:github.com/mozilla/public-restricted:pull-request", "sc"),
+ ("repo:github.com/mozilla/public-restricted:pull-request-untrusted", "sc"),
+ ("repo:github.com/mozilla/collaborators:pull-request", "sc"),
+ ]
+
+ def test_grant_to_star(self, add_scope):
+ grantee = ProjectGrantee(job=["*"])
+ grants.add_scopes_for_projects(
+ Grant(scopes=["sc"], grantees=[grantee]), grantee, add_scope, self.projects
+ )
+ pr_grants = [g for g in add_scope.added if "pull-request" in g[0]]
+
+ # Dump expected for copy/paste.
+ pprint(pr_grants)
+ assert pr_grants == [
+ ("repo:github.com/mozilla/public:pull-request", "sc"),
+ ("repo:github.com/mozilla/public-restricted:pull-request", "sc"),
+ ("repo:github.com/mozilla/public-restricted:pull-request-untrusted", "sc"),
+ ("repo:github.com/mozilla/collaborators:pull-request", "sc"),
+ ]
+
+ def test_include_pull_requests_false(self, add_scope):
+ grantee = ProjectGrantee(job=["pull-request:*"], include_pull_requests=False)
+ grants.add_scopes_for_projects(
+ Grant(scopes=["sc"], grantees=[grantee]), grantee, add_scope, self.projects
+ )
+ assert add_scope.added == []
+
+ def test_invalid_grantee(self):
+ grantee = ProjectGrantee(job=["pull-request"])
+ with pytest.raises(RuntimeError):
+ grants.add_scopes_for_projects(
+ Grant(scopes=["sc"], grantees=[grantee]),
+ grantee,
+ add_scope,
+ self.projects,
+ )
+
+
@pytest.mark.asyncio
async def test_update_resources(mock_ciconfig_file, set_environment):
mock_ciconfig_file(
"projects.yml",
{
"proj1": dict(
repo="https://hg.mozilla.org/foo/proj1",
repo_type="hg",