This is an automated email from the ASF dual-hosted git repository.
bneradt pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/trafficserver-ci.git
The following commit(s) were added to refs/heads/main by this push:
new 49af623 Add smart HTTP Git mirror service (#436)
49af623 is described below
commit 49af6232d2f7fcacaba610e5b8218467e2d754ce
Author: Brian Neradt <[email protected]>
AuthorDate: Wed Jun 10 18:25:49 2026 -0500
Add smart HTTP Git mirror service (#436)
Jenkins mirror clones are now served through a static HTTP export, which
forces CI fanout jobs to download dumb HTTP packs and makes PR checkouts
depend on broad ref fetches. That path can turn the controller into a
bottleneck even when the local mirror is fresh.
This adds a dedicated smart HTTP container and systemd unit that run
git-http-backend on 127.0.0.1:9417 behind the existing /mirror/ URLs. The
controller installer starts the service, mirror initialization disables
receive-pack, and the runbook documents rollout, verification, and
rollback.
This narrows PR child job refspecs to the target branch and current PR
head/merge refs with honorRefspec enabled. The mirror check scripts now
verify PR merge refs and can compare the mirrored head against
GITHUB_PR_HEAD_SHA.
---
github-mirror/README.md | 316 ++++++++++++++++++---
.../ats/mirror-smart-http-remap-snippet.config | 7 +
github-mirror/bin/check-docker-access.sh | 27 +-
github-mirror/bin/check-mirror.sh | 38 ++-
github-mirror/bin/init-mirrors.sh | 2 +
github-mirror/bin/install-controller.sh | 13 +
github-mirror/httpd/Dockerfile | 11 +
github-mirror/httpd/docker-compose.yml | 13 +
github-mirror/httpd/mirror.conf | 28 +-
.../systemd/github-mirror-smart-http.service | 20 ++
jenkins/github/autest.pipeline | 4 +-
jenkins/github/centos.pipeline | 4 +-
jenkins/github/clang-analyzer.pipeline | 4 +-
jenkins/github/debian.pipeline | 4 +-
jenkins/github/docs.pipeline | 4 +-
jenkins/github/fedora.pipeline | 4 +-
jenkins/github/format.pipeline | 4 +-
jenkins/github/freebsd.pipeline | 4 +-
jenkins/github/osx.pipeline | 4 +-
jenkins/github/rat.pipeline | 4 +-
jenkins/github/rocky-asan.pipeline | 4 +-
jenkins/github/rocky.pipeline | 4 +-
jenkins/github/ubuntu.pipeline | 4 +-
23 files changed, 457 insertions(+), 70 deletions(-)
diff --git a/github-mirror/README.md b/github-mirror/README.md
index ec09a39..e8acb61 100644
--- a/github-mirror/README.md
+++ b/github-mirror/README.md
@@ -32,12 +32,33 @@ https://ci.trafficserver.apache.org/github-mirror-webhook
v
/home/mirror/trafficserver.git
/home/mirror/trafficserver-ci.git
+ ^
+ | read-only bind mount
|
- | httpd export under /mirror/ plus git-daemon on 9418
+127.0.0.1:9417/mirror/
+ |
+ | dedicated httpd container running git-http-backend
+ v
+https://ci.trafficserver.apache.org/mirror/
+ |
+ | ATS remap, cache disabled
v
Jenkins controller and docker agents
```
+The supported Jenkins serving path is smart Git HTTP behind ATS. The public
+URLs stay under `https://ci.trafficserver.apache.org/mirror/`, but ATS remaps
+that path to a dedicated controller-local httpd container on `127.0.0.1:9417`.
+The container runs `git-http-backend` and mounts `/home/mirror` read-only.
+
+Static dumb HTTP is not acceptable for the Jenkins fanout path. It cannot
+negotiate packs with the client, so many child jobs can repeatedly download
+large static pack files and probe missing loose objects. Smart HTTP uses
+`git-upload-pack` so each clone/fetch gets a negotiated pack.
+
+`git-daemon` on port 9418 is kept only as a diagnostic or emergency fallback.
+Do not use `git://` URLs as the normal Jenkins configuration.
+
The webhook service only accepts signed GitHub payloads for:
- `apache/trafficserver`
@@ -83,15 +104,16 @@ Repositories and events:
Rationale:
Our Jenkins jobs run on a fleet of docker hosts behind the controller. The
jobs currently clone repeatedly from GitHub. We are moving those checkouts to
- a local read-only mirror on the controller. The webhook keeps branch and pull
- request refs current before Jenkins fans work out to the docker hosts.
+ a local read-only smart HTTP mirror on the controller. The webhook keeps
+ branch and pull request refs current before Jenkins fans work out to the
+ docker hosts.
Thanks.
```
## Fresh Controller Install
-These steps assume Ubuntu and a controller that will serve
+These steps assume Ubuntu and a controller that serves
`ci.trafficserver.apache.org` through ATS.
1. Clone or copy `trafficserver-ci` onto the controller.
@@ -109,13 +131,17 @@ These steps assume Ubuntu and a controller that will serve
The installer:
- - installs `git`, `git-daemon-sysvinit`, `python3`, and `util-linux`;
+ - installs `git`, `git-daemon-sysvinit`, `docker.io`, `docker-compose`,
+ `python3`, and `util-linux`;
- installs this package to `/opt/trafficserver-ci/github-mirror`;
- creates/configures `/home/mirror`;
- creates `/home/mirror/trafficserver.git`;
- creates `/home/mirror/trafficserver-ci.git`;
+ - configures both bare repos with `http.uploadpack=true` and
+ `http.receivepack=false`;
- installs systemd units;
- installs `/etc/default/git-daemon`;
+ - enables the smart HTTP container service;
- enables the fallback refresh timer.
3. Install the GitHub webhook secret.
@@ -138,7 +164,7 @@ These steps assume Ubuntu and a controller that will serve
sudo chmod 0600 /etc/trafficserver-github-mirror/github-mirror-webhook.env
```
-4. Configure the HTTPS webhook endpoint in ATS.
+4. Configure ATS remaps.
Add `github-mirror/ats/remap-snippet.config` before the generic
`ci.trafficserver.apache.org` Jenkins remap in:
@@ -147,38 +173,140 @@ These steps assume Ubuntu and a controller that will
serve
/opt/ats/etc/trafficserver/remap.config
```
+ Add or update the `/mirror/` remap with
+ `github-mirror/ats/mirror-smart-http-remap-snippet.config`. The important
+ change is:
+
+ ```text
+ https://ci.trafficserver.apache.org/mirror/ -> http://localhost:9417/mirror/
+ ```
+
+ Keep `proxy.config.http.cache.http=0`. Keep `hdr_rw_git.config` unless
+ testing proves it interferes with smart Git POSTs. Remove the mirror purge
+ plugin from this remap. Do not change the docs httpd/container remaps.
+
Reload ATS:
```bash
sudo /opt/ats/bin/traffic_ctl config reload
```
-5. Export `/home/mirror` as `/mirror/`.
+5. Verify the smart HTTP service.
- If the controller already has httpd serving `/mirror/`, keep that setup.
- For a fresh controller, use `github-mirror/httpd/mirror.conf` as the
- reference config for the httpd instance behind ATS. The updater runs
- `git update-server-info`, so a static HTTP export is sufficient.
+ ```bash
+ sudo systemctl status github-mirror-smart-http.service
+
+ cd /opt/trafficserver-ci/github-mirror/httpd
+ sudo docker-compose config
+ sudo docker exec github-mirror-smart-http httpd -t
+
+ git ls-remote http://127.0.0.1:9417/mirror/trafficserver.git
refs/heads/master
+ git ls-remote http://127.0.0.1:9417/mirror/trafficserver-ci.git
refs/heads/main
+ ```
-6. Start the webhook receiver.
+6. Start the webhook receiver after the secret is installed.
```bash
sudo systemctl restart github-mirror-webhook.service
sudo systemctl status github-mirror-webhook.service
```
-7. Confirm the timer and git-daemon are active.
+7. Confirm the timer and diagnostic git-daemon are active.
```bash
systemctl list-timers github-mirror-fallback.timer
sudo service git-daemon status
```
+8. Verify the public HTTPS mirror and at least one docker host.
+
+ ```bash
+ /opt/trafficserver-ci/github-mirror/bin/check-mirror.sh --pr
<open-pr-number>
+
+ CONTROLLER=- \
+ /opt/trafficserver-ci/github-mirror/bin/check-docker-access.sh \
+ --pr <open-pr-number> docker12
+ ```
+
+ To verify the exact PR head Jenkins is about to build:
+
+ ```bash
+ GITHUB_PR_HEAD_SHA=<sha-from-jenkins-or-github> \
+ /opt/trafficserver-ci/github-mirror/bin/check-mirror.sh --pr
<open-pr-number>
+ ```
+
+## Existing Controller Rollout
+
+1. Commit and merge the repo changes.
+
+2. Pull the merged branch into `/opt/trafficserver-ci` on `controller`.
+
+ ```bash
+ ssh controller
+ cd /opt/trafficserver-ci
+ sudo git pull --ff-only
+ ```
+
+3. Install or refresh the controller files.
+
+ ```bash
+ sudo github-mirror/bin/install-controller.sh
+ ```
+
+ If ASF webhooks are not ready yet, use the interim cron rollout below.
+
+4. Build/start the smart HTTP service and validate httpd.
+
+ ```bash
+ sudo systemctl enable --now github-mirror-smart-http.service
+ cd /opt/trafficserver-ci/github-mirror/httpd
+ sudo docker-compose config
+ sudo docker exec github-mirror-smart-http httpd -t
+ ```
+
+5. Update the ATS `/mirror/` remap to point at `http://localhost:9417/mirror/`.
+ Keep cache disabled and remove the mirror purge plugin from this remap.
+
+ ```bash
+ sudo /opt/ats/bin/traffic_ctl config reload
+ ```
+
+6. Verify from controller and at least one docker host.
+
+ ```bash
+ /opt/trafficserver-ci/github-mirror/bin/check-mirror.sh --pr
<open-pr-number>
+
+ CONTROLLER=- \
+ /opt/trafficserver-ci/github-mirror/bin/check-docker-access.sh \
+ --pr <open-pr-number> docker12
+ ```
+
+7. Confirm the smart HTTP logs show Git requests instead of dumb HTTP object
+ probing.
+
+ ```bash
+ sudo tail -f /var/log/github-mirror-smart-http/access_log
+ ```
+
+ Healthy Jenkins clones should include `git-upload-pack` requests. They
should
+ not produce thousands of loose-object 404s.
+
+8. Run a small PR fanout subset before broadening:
+
+ ```text
+ docs
+ rocky
+ one autest shard
+ ```
+
+ Also confirm existing docs URLs still work through the existing docs
+ container.
+
## Interim Cron Rollout
Use this section while ASF Infra is still setting up the GitHub webhooks. The
-cron updater keeps the mirrors fresh enough for Jenkins by fetching heads,
tags,
-and ATS pull request refs every five minutes.
+temporary cron updater fetches heads, tags, and ATS pull request refs every
+minute.
1. Install the current `trafficserver-ci` branch on `controller`.
@@ -201,7 +329,9 @@ and ATS pull request refs every five minutes.
This initializes `/home/mirror/trafficserver.git` and
`/home/mirror/trafficserver-ci.git`, installs the scripts under
- `/opt/trafficserver-ci/github-mirror`, and starts `git-daemon`.
+ `/opt/trafficserver-ci/github-mirror`, starts diagnostic `git-daemon`, and
+ starts the smart HTTP service. Set `START_SMART_HTTP=0` only if you are not
+ ready to change the ATS `/mirror/` remap yet.
3. Install the temporary cron file.
@@ -212,6 +342,13 @@ and ATS pull request refs every five minutes.
sudo systemctl restart cron
```
+ Check it is installed:
+
+ ```bash
+ sudo cat /etc/cron.d/github-mirror
+ grep github-mirror /var/log/syslog
+ ```
+
4. Run one manual refresh and verify refs.
```bash
@@ -232,14 +369,15 @@ and ATS pull request refs every five minutes.
From any checkout of this repo on a host that can SSH through `controller`:
```bash
- github-mirror/bin/check-docker-access.sh docker12
+ github-mirror/bin/check-docker-access.sh --pr <pr-number> docker12
```
From `controller` itself:
```bash
CONTROLLER=- \
- /opt/trafficserver-ci/github-mirror/bin/check-docker-access.sh docker12
+ /opt/trafficserver-ci/github-mirror/bin/check-docker-access.sh \
+ --pr <pr-number> docker12
```
6. Update Jenkins job configuration so the PR and branch top-level jobs pass
@@ -255,21 +393,14 @@ and ATS pull request refs every five minutes.
Then run a small PR job such as docs or RAT before starting the full build
fanout.
-7. Watch the cron updater and Jenkins checkouts.
-
- ```bash
- grep github-mirror /var/log/syslog
- git ls-remote https://ci.trafficserver.apache.org/mirror/trafficserver.git \
- refs/heads/master
- ```
-
-8. When ASF webhooks are available, install the secret, start the webhook, send
+7. When ASF webhooks are available, install the secret, start the webhook, send
a GitHub ping delivery, then remove the temporary cron file.
```bash
sudo systemctl restart github-mirror-webhook.service
sudo rm -f /etc/cron.d/github-mirror
sudo systemctl restart cron
+ sudo systemctl enable --now github-mirror-fallback.timer
```
## Mirror Operations
@@ -312,10 +443,19 @@ Check from docker agents:
/opt/trafficserver-ci/github-mirror/bin/check-docker-access.sh --pr 12345
docker1 docker12
```
-When running that command directly on the controller, use:
+Inspect smart HTTP:
```bash
-CONTROLLER=- /opt/trafficserver-ci/github-mirror/bin/check-docker-access.sh
docker12
+sudo systemctl status github-mirror-smart-http.service
+cd /opt/trafficserver-ci/github-mirror/httpd
+sudo docker-compose logs --tail=100 github-mirror-smart-http
+sudo tail -n 100 /var/log/github-mirror-smart-http/access_log
+```
+
+Use `git-daemon` only as a diagnostic fallback:
+
+```bash
+git ls-remote git://ci.trafficserver.apache.org/trafficserver.git
refs/heads/master
```
## Webhook Testing
@@ -329,8 +469,56 @@ View logs:
journalctl -u github-mirror-webhook.service -f
```
+Local signed ping test:
+
+```bash
+secret=$(sudo awk -F= '/^GITHUB_WEBHOOK_SECRET=/ { print $2 }' \
+ /etc/trafficserver-github-mirror/github-mirror-webhook.env)
+body='{"repository":{"full_name":"apache/trafficserver"}}'
+sig=$(SECRET="$secret" BODY="$body" python3 - <<'PY'
+import hashlib
+import hmac
+import os
+
+print(
+ "sha256="
+ + hmac.new(
+ os.environ["SECRET"].encode(),
+ os.environ["BODY"].encode(),
+ hashlib.sha256,
+ ).hexdigest()
+)
+PY
+)
+
+curl -i \
+ -H "X-GitHub-Event: ping" \
+ -H "X-Hub-Signature-256: ${sig}" \
+ --data "${body}" \
+ http://127.0.0.1:9419/github-mirror-webhook
+```
+
A bad secret or unsigned payload should return HTTP 401 and must not update any
-repository.
+repository:
+
+```bash
+curl -i \
+ -H "X-GitHub-Event: ping" \
+ -H "X-Hub-Signature-256: sha256=bad" \
+ --data "${body}" \
+ http://127.0.0.1:9419/github-mirror-webhook
+```
+
+Anonymous push attempts must fail:
+
+```bash
+GIT_TERMINAL_PROMPT=0 \
+ git push https://ci.trafficserver.apache.org/mirror/trafficserver.git \
+ HEAD:refs/heads/github-mirror-push-test
+```
+
+The expected result is rejection because the bare repositories have
+`http.receivepack=false` and the service does not allow receive-pack.
## Jenkins Integration
@@ -347,12 +535,22 @@ For GitHub PR jobs, configure the top-level job's
`GITHUB_URL` parameter to:
https://ci.trafficserver.apache.org/mirror/trafficserver.git
```
-The top-level pipeline passes that value to child jobs. During the temporary
-cron rollout, set the top-level PR job quiet period to at least 90 seconds.
Once
-the webhook is live and verified, the quiet period can be removed or reduced.
+The repo-managed PR pipeline scripts fetch:
+
+- the target branch;
+- only the current PR's `refs/pull/<number>/head`;
+- only the current PR's `refs/pull/<number>/merge`.
+
+They also use `CloneOption(honorRefspec: true, timeout: 20)` so Jenkins does
+not fan out a wildcard PR ref fetch to every child job.
+
+During the temporary cron rollout, set the top-level PR job quiet period to at
+least 90 seconds. Once the webhook is live and verified, the quiet period can
+be removed or reduced.
For branch jobs, configure the top-level branch jobs' `GITHUB_URL` parameter to
the same ATS mirror URL. Child jobs will receive that value from the fanout
job.
+Branch jobs continue using normal branch checkouts from the mirror URL.
## Migrating An Existing Controller
@@ -384,21 +582,42 @@ Do not delete the old scripts until the new path has run
for a few days.
## Rollback
-1. Stop webhook updates.
+The Jenkins URLs do not need to change for a smart HTTP rollback because the
+public `/mirror/` URLs stay the same.
+
+1. Change the ATS `/mirror/` remap back to the previous static backend:
+
+ ```text
+ https://ci.trafficserver.apache.org/mirror/ -> http://localhost:8080/mirror/
+ ```
+
+2. Reload ATS.
```bash
- sudo systemctl stop github-mirror-webhook.service
- sudo systemctl stop github-mirror-fallback.timer
+ sudo /opt/ats/bin/traffic_ctl config reload
```
-2. Point Jenkins job parameters back at GitHub:
+3. Stop the smart HTTP service.
- ```text
- https://github.com/apache/trafficserver.git
- https://github.com/apache/trafficserver-ci.git
+ ```bash
+ sudo systemctl disable --now github-mirror-smart-http.service
```
-3. If needed, re-enable the previous cron updater.
+4. If the mirror update path is also being rolled back, stop webhook updates
+ and re-enable the previous cron updater.
+
+ ```bash
+ sudo systemctl stop github-mirror-webhook.service
+ sudo systemctl stop github-mirror-fallback.timer
+ ```
+
+Full rollback to GitHub is still possible by pointing Jenkins job parameters
+back at:
+
+```text
+https://github.com/apache/trafficserver.git
+https://github.com/apache/trafficserver-ci.git
+```
Rollback does not require deleting `/home/mirror`.
@@ -410,6 +629,7 @@ Missing PR ref:
sudo -u gitdaemon \
/opt/trafficserver-ci/github-mirror/bin/update-mirror.sh trafficserver --pr
<number>
git --git-dir=/home/mirror/trafficserver.git show-ref refs/pull/<number>/head
+git --git-dir=/home/mirror/trafficserver.git show-ref refs/pull/<number>/merge
```
Webhook returns 401:
@@ -425,13 +645,25 @@ Webhook returns 401:
Jenkins cannot clone from HTTPS:
- Verify ATS remap order.
-- Verify the httpd `/mirror/` export.
+- Verify `/mirror/` points to `http://localhost:9417/mirror/`.
+- Verify the smart HTTP service is healthy.
- Verify the public URL:
```bash
+ sudo systemctl status github-mirror-smart-http.service
+ sudo docker exec github-mirror-smart-http httpd -t
git ls-remote https://ci.trafficserver.apache.org/mirror/trafficserver.git
refs/heads/master
```
+Jenkins fetches look like dumb HTTP:
+
+- Confirm ATS is using the smart HTTP remap, not
`http://localhost:8080/mirror/`.
+- Confirm logs include `git-upload-pack`:
+
+ ```bash
+ sudo tail -n 100 /var/log/github-mirror-smart-http/access_log
+ ```
+
Docker hosts cannot reach the mirror:
```bash
diff --git a/github-mirror/ats/mirror-smart-http-remap-snippet.config
b/github-mirror/ats/mirror-smart-http-remap-snippet.config
new file mode 100644
index 0000000..e4517be
--- /dev/null
+++ b/github-mirror/ats/mirror-smart-http-remap-snippet.config
@@ -0,0 +1,7 @@
+# Put this before the generic Jenkins/ci.trafficserver.apache.org catch-all
remap.
+#
+# Smart Git HTTP traffic is served by github-mirror-smart-http on the
+# controller. Do not cache these responses in ATS.
+map https://ci.trafficserver.apache.org/mirror/ http://localhost:9417/mirror/ \
+ @plugin=conf_remap.so @pparam=proxy.config.http.cache.http=0 \
+ @plugin=header_rewrite.so @pparam=hdr_rw_git.config
diff --git a/github-mirror/bin/check-docker-access.sh
b/github-mirror/bin/check-docker-access.sh
index 6156f03..01b351c 100755
--- a/github-mirror/bin/check-docker-access.sh
+++ b/github-mirror/bin/check-docker-access.sh
@@ -7,6 +7,7 @@ set -euo pipefail
CONTROLLER=${CONTROLLER:-controller}
PUBLIC_BASE=${PUBLIC_BASE:-https://ci.trafficserver.apache.org/mirror}
PR_NUMBER=${PR_NUMBER:-}
+GITHUB_PR_HEAD_SHA=${GITHUB_PR_HEAD_SHA:-}
usage() {
cat <<'EOF'
@@ -20,6 +21,8 @@ Environment:
Set to empty or "-" when running directly on the controller.
PUBLIC_BASE Public HTTPS mirror base URL. Default:
https://ci.trafficserver.apache.org/mirror
PR_NUMBER Optional PR number to verify.
+ GITHUB_PR_HEAD_SHA
+ Optional expected PR head SHA to compare against --pr.
EOF
}
@@ -55,12 +58,28 @@ for docker_host in "$@"; do
ssh_args+=(-J "${CONTROLLER}")
fi
ssh "${ssh_args[@]}" "${docker_host}" \
- "PUBLIC_BASE=$(printf '%q' "${PUBLIC_BASE}") PR_NUMBER=$(printf '%q'
"${PR_NUMBER}") bash -s" <<'REMOTE_CHECK'
+ "PUBLIC_BASE=$(printf '%q' "${PUBLIC_BASE}") PR_NUMBER=$(printf '%q'
"${PR_NUMBER}") GITHUB_PR_HEAD_SHA=$(printf '%q' "${GITHUB_PR_HEAD_SHA}") bash
-s" <<'REMOTE_CHECK'
set -e
-git ls-remote "$PUBLIC_BASE/trafficserver.git" refs/heads/master >/dev/null
-git ls-remote "$PUBLIC_BASE/trafficserver-ci.git" refs/heads/main >/dev/null
+require_ref() {
+ repo=$1
+ ref=$2
+ output=$(git ls-remote "$PUBLIC_BASE/${repo}.git" "$ref")
+ if [ -z "$output" ]; then
+ echo "missing ${repo} ${ref}" >&2
+ exit 1
+ fi
+ printf '%s\n' "$output" | awk 'NR == 1 { print $1 }'
+}
+
+require_ref trafficserver refs/heads/master >/dev/null
+require_ref trafficserver-ci refs/heads/main >/dev/null
if [ -n "$PR_NUMBER" ]; then
- git ls-remote "$PUBLIC_BASE/trafficserver.git" "refs/pull/${PR_NUMBER}/head"
>/dev/null
+ pr_head_sha=$(require_ref trafficserver "refs/pull/${PR_NUMBER}/head")
+ require_ref trafficserver "refs/pull/${PR_NUMBER}/merge" >/dev/null
+ if [ -n "$GITHUB_PR_HEAD_SHA" ] && [ "$pr_head_sha" != "$GITHUB_PR_HEAD_SHA"
]; then
+ echo "PR head ${pr_head_sha} does not match
GITHUB_PR_HEAD_SHA=${GITHUB_PR_HEAD_SHA}" >&2
+ exit 1
+ fi
fi
REMOTE_CHECK
done
diff --git a/github-mirror/bin/check-mirror.sh
b/github-mirror/bin/check-mirror.sh
index 2078689..a292f3c 100755
--- a/github-mirror/bin/check-mirror.sh
+++ b/github-mirror/bin/check-mirror.sh
@@ -8,6 +8,7 @@ MIRROR_ROOT=${MIRROR_ROOT:-/home/mirror}
PUBLIC_BASE=${PUBLIC_BASE:-https://ci.trafficserver.apache.org/mirror}
GIT=${GIT:-git}
PR_NUMBER=${PR_NUMBER:-}
+GITHUB_PR_HEAD_SHA=${GITHUB_PR_HEAD_SHA:-}
usage() {
cat <<'EOF'
@@ -19,6 +20,8 @@ Environment:
PUBLIC_BASE Public HTTPS mirror base URL. Default:
https://ci.trafficserver.apache.org/mirror
GIT Git executable. Default: git
PR_NUMBER Optional PR number to verify.
+ GITHUB_PR_HEAD_SHA
+ Optional expected PR head SHA to compare against --pr.
EOF
}
@@ -59,13 +62,28 @@ check_local_ref() {
log "local ${repo} has ${ref}"
}
-check_remote_ref() {
+local_ref_sha() {
+ local repo=$1
+ local ref=$2
+ local repo_dir="${MIRROR_ROOT}/${repo}.git"
+ "${GIT}" --git-dir="${repo_dir}" rev-parse "${ref}^{commit}"
+}
+
+remote_ref_sha() {
local repo=$1
local ref=$2
local url="${PUBLIC_BASE}/${repo}.git"
local output
output=$("${GIT}" ls-remote "${url}" "${ref}")
[ -n "${output}" ] || die "missing public ref ${ref} at ${url}"
+ printf '%s\n' "${output}" | awk 'NR == 1 { print $1 }'
+}
+
+check_remote_ref() {
+ local repo=$1
+ local ref=$2
+ local url="${PUBLIC_BASE}/${repo}.git"
+ remote_ref_sha "${repo}" "${ref}" >/dev/null
log "public ${url} has ${ref}"
}
@@ -76,8 +94,22 @@ check_remote_ref trafficserver-ci refs/heads/main
if [ -n "${PR_NUMBER}" ]; then
[[ "${PR_NUMBER}" =~ ^[0-9]+$ ]] || die "invalid PR number: ${PR_NUMBER}"
- check_local_ref trafficserver "refs/pull/${PR_NUMBER}/head"
- check_remote_ref trafficserver "refs/pull/${PR_NUMBER}/head"
+ pr_head_ref="refs/pull/${PR_NUMBER}/head"
+ pr_merge_ref="refs/pull/${PR_NUMBER}/merge"
+ check_local_ref trafficserver "${pr_head_ref}"
+ check_remote_ref trafficserver "${pr_head_ref}"
+ check_local_ref trafficserver "${pr_merge_ref}"
+ check_remote_ref trafficserver "${pr_merge_ref}"
+
+ if [ -n "${GITHUB_PR_HEAD_SHA}" ]; then
+ local_head_sha=$(local_ref_sha trafficserver "${pr_head_ref}")
+ public_head_sha=$(remote_ref_sha trafficserver "${pr_head_ref}")
+ [ "${local_head_sha}" = "${GITHUB_PR_HEAD_SHA}" ] ||
+ die "local PR head ${local_head_sha} does not match
GITHUB_PR_HEAD_SHA=${GITHUB_PR_HEAD_SHA}"
+ [ "${public_head_sha}" = "${GITHUB_PR_HEAD_SHA}" ] ||
+ die "public PR head ${public_head_sha} does not match
GITHUB_PR_HEAD_SHA=${GITHUB_PR_HEAD_SHA}"
+ log "PR head matches GITHUB_PR_HEAD_SHA=${GITHUB_PR_HEAD_SHA}"
+ fi
fi
log "mirror checks passed"
diff --git a/github-mirror/bin/init-mirrors.sh
b/github-mirror/bin/init-mirrors.sh
index 85243d7..976295c 100755
--- a/github-mirror/bin/init-mirrors.sh
+++ b/github-mirror/bin/init-mirrors.sh
@@ -83,6 +83,8 @@ init_repo() {
fi
configure_remote "${repo_dir}" "${remote_url}" "$@"
+ "${GIT}" --git-dir="${repo_dir}" config http.uploadpack true
+ "${GIT}" --git-dir="${repo_dir}" config http.receivepack false
touch "${repo_dir}/git-daemon-export-ok"
if [ "$(id -u)" -eq 0 ]; then
diff --git a/github-mirror/bin/install-controller.sh
b/github-mirror/bin/install-controller.sh
index 88be0ca..9bd0ab5 100755
--- a/github-mirror/bin/install-controller.sh
+++ b/github-mirror/bin/install-controller.sh
@@ -16,6 +16,7 @@ ENV_FILE=${ENV_FILE:-${ENV_DIR}/github-mirror-webhook.env}
APT_INSTALL=${APT_INSTALL:-1}
START_WEBHOOK=${START_WEBHOOK:-auto}
START_FALLBACK_TIMER=${START_FALLBACK_TIMER:-1}
+START_SMART_HTTP=${START_SMART_HTTP:-1}
INIT_MIRRORS=${INIT_MIRRORS:-1}
usage() {
@@ -34,6 +35,8 @@ Environment:
START_WEBHOOK auto, 1, or 0. Default: auto
START_FALLBACK_TIMER
Enable/start the systemd fallback timer when set to 1.
Default: 1
+ START_SMART_HTTP
+ Enable/start smart HTTP mirror service when set to 1.
Default: 1
EOF
}
@@ -76,6 +79,8 @@ if [ "${APT_INSTALL}" = "1" ]; then
DEBIAN_FRONTEND=noninteractive apt-get install -y \
git \
git-daemon-sysvinit \
+ docker.io \
+ docker-compose \
python3 \
util-linux
fi
@@ -114,6 +119,8 @@ render_template
"${INSTALL_ROOT}/systemd/github-mirror-fallback.service" "${tmp_
install -o root -g root -m 0644 "${tmp_unit}"
/etc/systemd/system/github-mirror-fallback.service
render_template "${INSTALL_ROOT}/systemd/github-mirror-fallback.timer"
"${tmp_unit}"
install -o root -g root -m 0644 "${tmp_unit}"
/etc/systemd/system/github-mirror-fallback.timer
+render_template "${INSTALL_ROOT}/systemd/github-mirror-smart-http.service"
"${tmp_unit}"
+install -o root -g root -m 0644 "${tmp_unit}"
/etc/systemd/system/github-mirror-smart-http.service
rm -f "${tmp_unit}"
systemctl daemon-reload
@@ -132,6 +139,12 @@ else
systemctl disable --now github-mirror-fallback.timer >/dev/null 2>&1 || true
fi
+if [ "${START_SMART_HTTP}" = "1" ]; then
+ systemctl enable --now github-mirror-smart-http.service
+else
+ systemctl disable --now github-mirror-smart-http.service >/dev/null 2>&1 ||
true
+fi
+
if [ "${START_WEBHOOK}" = "1" ] ||
{ [ "${START_WEBHOOK}" = "auto" ] && grep -q '^GITHUB_WEBHOOK_SECRET='
"${ENV_FILE}" &&
! grep -q '^GITHUB_WEBHOOK_SECRET=CHANGE_ME' "${ENV_FILE}"; }; then
diff --git a/github-mirror/httpd/Dockerfile b/github-mirror/httpd/Dockerfile
new file mode 100644
index 0000000..c7d6b5c
--- /dev/null
+++ b/github-mirror/httpd/Dockerfile
@@ -0,0 +1,11 @@
+FROM httpd:2.4
+
+RUN apt-get update \
+ && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends
\
+ ca-certificates \
+ git \
+ && rm -rf /var/lib/apt/lists/*
+
+COPY mirror.conf /usr/local/apache2/conf/extra/github-mirror.conf
+
+RUN printf '\nInclude conf/extra/github-mirror.conf\n' >>
/usr/local/apache2/conf/httpd.conf
diff --git a/github-mirror/httpd/docker-compose.yml
b/github-mirror/httpd/docker-compose.yml
new file mode 100644
index 0000000..b0ec2da
--- /dev/null
+++ b/github-mirror/httpd/docker-compose.yml
@@ -0,0 +1,13 @@
+version: '3'
+
+services:
+ github-mirror-smart-http:
+ build: .
+ image: trafficserver/github-mirror-smart-http:latest
+ container_name: github-mirror-smart-http
+ restart: unless-stopped
+ ports:
+ - "127.0.0.1:9417:80"
+ volumes:
+ - /home/mirror:/usr/local/apache2/mirror:ro
+ - /var/log/github-mirror-smart-http:/usr/local/apache2/logs
diff --git a/github-mirror/httpd/mirror.conf b/github-mirror/httpd/mirror.conf
index abfce7a..4849158 100644
--- a/github-mirror/httpd/mirror.conf
+++ b/github-mirror/httpd/mirror.conf
@@ -1,14 +1,26 @@
-# Apache httpd snippet for exporting /home/mirror as /mirror/.
+# Smart Git HTTP export for the ATS CI GitHub mirrors.
#
-# This simple static export works with `git update-server-info`, which the
-# mirror updater runs after every fetch. If the controller already has an httpd
-# container or vhost serving /mirror/, keep that and use this as the rebuild
-# reference.
+# This is included by the dedicated github-mirror-smart-http container. ATS
+# terminates public HTTPS and remaps /mirror/ traffic to this container on
+# 127.0.0.1:9417.
-Alias /mirror/ /home/mirror/
+<IfModule !cgid_module>
+ LoadModule cgid_module modules/mod_cgid.so
+</IfModule>
-<Directory /home/mirror/>
- Options Indexes FollowSymLinks
+SetEnv GIT_PROJECT_ROOT /usr/local/apache2/mirror
+SetEnv GIT_HTTP_EXPORT_ALL 1
+
+CustomLog "logs/access_log" combined
+
+ScriptAlias /mirror/ /usr/lib/git-core/git-http-backend/
+
+<Directory "/usr/lib/git-core">
+ Options +ExecCGI
AllowOverride None
Require all granted
</Directory>
+
+<LocationMatch "^/mirror/.*/git-receive-pack$">
+ Require all denied
+</LocationMatch>
diff --git a/github-mirror/systemd/github-mirror-smart-http.service
b/github-mirror/systemd/github-mirror-smart-http.service
new file mode 100644
index 0000000..e9c96f0
--- /dev/null
+++ b/github-mirror/systemd/github-mirror-smart-http.service
@@ -0,0 +1,20 @@
+[Unit]
+Description=ATS CI GitHub mirror smart HTTP service
+Documentation=file:@INSTALL_ROOT@/README.md
+After=network-online.target docker.service
+Wants=network-online.target
+Requires=docker.service
+
+[Service]
+Type=simple
+WorkingDirectory=@INSTALL_ROOT@/httpd
+ExecStartPre=/usr/bin/install -d -o root -g root -m 0755
/var/log/github-mirror-smart-http
+ExecStartPre=/usr/bin/docker-compose build
+ExecStart=/usr/bin/docker-compose up --remove-orphans
+ExecStop=/usr/bin/docker-compose down
+Restart=on-failure
+RestartSec=5s
+TimeoutStartSec=10min
+
+[Install]
+WantedBy=multi-user.target
diff --git a/jenkins/github/autest.pipeline b/jenkins/github/autest.pipeline
index 7b2e939..c9e6f2d 100644
--- a/jenkins/github/autest.pipeline
+++ b/jenkins/github/autest.pipeline
@@ -45,6 +45,7 @@ pipeline {
checkout([$class: 'GitSCM',
branches: [[name: sha1]],
extensions: [
+ [$class: 'CloneOption', honorRefspec: true, timeout: 20],
// We have to set an idenity for the merge step because Git
requires
// the user.name and user.email to be set to do a merge.
[$class: "UserIdentity",
@@ -60,7 +61,8 @@ pipeline {
]
],
],
- userRemoteConfigs: [[url: github_url, refspec:
'+refs/pull/*:refs/remotes/origin/pr/*']]])
+ userRemoteConfigs: [[url: github_url,
+ refspec:
"+refs/heads/${GITHUB_PR_TARGET_BRANCH}:refs/remotes/origin/${GITHUB_PR_TARGET_BRANCH}
+refs/pull/${GITHUB_PR_NUMBER}/head:refs/remotes/origin/pr/${GITHUB_PR_NUMBER}/head
+refs/pull/${GITHUB_PR_NUMBER}/merge:refs/remotes/origin/pr/${GITHUB_PR_NUMBER}/merge"]])
sh '''#!/bin/bash
set -x
diff --git a/jenkins/github/centos.pipeline b/jenkins/github/centos.pipeline
index 5d6b577..ccba76e 100644
--- a/jenkins/github/centos.pipeline
+++ b/jenkins/github/centos.pipeline
@@ -19,6 +19,7 @@ pipeline {
checkout([$class: 'GitSCM',
branches: [[name: sha1]],
extensions: [
+ [$class: 'CloneOption', honorRefspec: true,
timeout: 20],
// We have to set an idenity for the merge step
because Git requires
// the user.name and user.email to be set to do a
merge.
[$class: "UserIdentity",
@@ -34,7 +35,8 @@ pipeline {
]
],
],
- userRemoteConfigs: [[url: github_url, refspec:
'+refs/pull/*:refs/remotes/origin/pr/*']]])
+ userRemoteConfigs: [[url: github_url,
+ refspec:
"+refs/heads/${GITHUB_PR_TARGET_BRANCH}:refs/remotes/origin/${GITHUB_PR_TARGET_BRANCH}
+refs/pull/${GITHUB_PR_NUMBER}/head:refs/remotes/origin/pr/${GITHUB_PR_NUMBER}/head
+refs/pull/${GITHUB_PR_NUMBER}/merge:refs/remotes/origin/pr/${GITHUB_PR_NUMBER}/merge"]])
sh '''#!/bin/bash
set -x
diff --git a/jenkins/github/clang-analyzer.pipeline
b/jenkins/github/clang-analyzer.pipeline
index e11ebf3..6c60359 100644
--- a/jenkins/github/clang-analyzer.pipeline
+++ b/jenkins/github/clang-analyzer.pipeline
@@ -15,6 +15,7 @@ pipeline {
checkout([$class: 'GitSCM',
branches: [[name: sha1]],
extensions: [
+ [$class: 'CloneOption', honorRefspec: true,
timeout: 20],
// We have to set an idenity for the merge step
because Git requires
// the user.name and user.email to be set to do a
merge.
[$class: "UserIdentity",
@@ -30,7 +31,8 @@ pipeline {
]
],
],
- userRemoteConfigs: [[url: github_url, refspec:
'+refs/pull/*:refs/remotes/origin/pr/*']]])
+ userRemoteConfigs: [[url: github_url,
+ refspec:
"+refs/heads/${GITHUB_PR_TARGET_BRANCH}:refs/remotes/origin/${GITHUB_PR_TARGET_BRANCH}
+refs/pull/${GITHUB_PR_NUMBER}/head:refs/remotes/origin/pr/${GITHUB_PR_NUMBER}/head
+refs/pull/${GITHUB_PR_NUMBER}/merge:refs/remotes/origin/pr/${GITHUB_PR_NUMBER}/merge"]])
sh '''#!/bin/bash
set -x
diff --git a/jenkins/github/debian.pipeline b/jenkins/github/debian.pipeline
index b1152d7..ac223c6 100644
--- a/jenkins/github/debian.pipeline
+++ b/jenkins/github/debian.pipeline
@@ -19,6 +19,7 @@ pipeline {
checkout([$class: 'GitSCM',
branches: [[name: sha1]],
extensions: [
+ [$class: 'CloneOption', honorRefspec: true,
timeout: 20],
// We have to set an idenity for the merge step
because Git requires
// the user.name and user.email to be set to do a
merge.
[$class: "UserIdentity",
@@ -34,7 +35,8 @@ pipeline {
]
],
],
- userRemoteConfigs: [[url: github_url, refspec:
'+refs/pull/*:refs/remotes/origin/pr/*']]])
+ userRemoteConfigs: [[url: github_url,
+ refspec:
"+refs/heads/${GITHUB_PR_TARGET_BRANCH}:refs/remotes/origin/${GITHUB_PR_TARGET_BRANCH}
+refs/pull/${GITHUB_PR_NUMBER}/head:refs/remotes/origin/pr/${GITHUB_PR_NUMBER}/head
+refs/pull/${GITHUB_PR_NUMBER}/merge:refs/remotes/origin/pr/${GITHUB_PR_NUMBER}/merge"]])
sh '''#!/bin/bash
set -x
diff --git a/jenkins/github/docs.pipeline b/jenkins/github/docs.pipeline
index 1ddf7cb..5b05109 100644
--- a/jenkins/github/docs.pipeline
+++ b/jenkins/github/docs.pipeline
@@ -16,6 +16,7 @@ pipeline {
checkout([$class: 'GitSCM',
branches: [[name: sha1]],
extensions: [
+ [$class: 'CloneOption', honorRefspec: true,
timeout: 20],
// We have to set an idenity for the merge step
because Git requires
// the user.name and user.email to be set to do a
merge.
[$class: "UserIdentity",
@@ -31,7 +32,8 @@ pipeline {
]
],
],
- userRemoteConfigs: [[url: github_url, refspec:
'+refs/pull/*:refs/remotes/origin/pr/*']]])
+ userRemoteConfigs: [[url: github_url,
+ refspec:
"+refs/heads/${GITHUB_PR_TARGET_BRANCH}:refs/remotes/origin/${GITHUB_PR_TARGET_BRANCH}
+refs/pull/${GITHUB_PR_NUMBER}/head:refs/remotes/origin/pr/${GITHUB_PR_NUMBER}/head
+refs/pull/${GITHUB_PR_NUMBER}/merge:refs/remotes/origin/pr/${GITHUB_PR_NUMBER}/merge"]])
sh '''#!/bin/bash
set -x
diff --git a/jenkins/github/fedora.pipeline b/jenkins/github/fedora.pipeline
index 23e6c07..7c738a8 100644
--- a/jenkins/github/fedora.pipeline
+++ b/jenkins/github/fedora.pipeline
@@ -19,6 +19,7 @@ pipeline {
checkout([$class: 'GitSCM',
branches: [[name: sha1]],
extensions: [
+ [$class: 'CloneOption', honorRefspec: true,
timeout: 20],
// We have to set an idenity for the merge step
because Git requires
// the user.name and user.email to be set to do a
merge.
[$class: "UserIdentity",
@@ -34,7 +35,8 @@ pipeline {
]
],
],
- userRemoteConfigs: [[url: github_url, refspec:
'+refs/pull/*:refs/remotes/origin/pr/*']]])
+ userRemoteConfigs: [[url: github_url,
+ refspec:
"+refs/heads/${GITHUB_PR_TARGET_BRANCH}:refs/remotes/origin/${GITHUB_PR_TARGET_BRANCH}
+refs/pull/${GITHUB_PR_NUMBER}/head:refs/remotes/origin/pr/${GITHUB_PR_NUMBER}/head
+refs/pull/${GITHUB_PR_NUMBER}/merge:refs/remotes/origin/pr/${GITHUB_PR_NUMBER}/merge"]])
sh '''#!/bin/bash
set -x
diff --git a/jenkins/github/format.pipeline b/jenkins/github/format.pipeline
index ab61f23..d991368 100644
--- a/jenkins/github/format.pipeline
+++ b/jenkins/github/format.pipeline
@@ -16,6 +16,7 @@ pipeline {
checkout([$class: 'GitSCM',
branches: [[name: sha1]],
extensions: [
+ [$class: 'CloneOption', honorRefspec: true,
timeout: 20],
// We have to set an idenity for the merge step
because Git requires
// the user.name and user.email to be set to do a
merge.
[$class: "UserIdentity",
@@ -31,7 +32,8 @@ pipeline {
]
],
],
- userRemoteConfigs: [[url: github_url, refspec:
'+refs/pull/*:refs/remotes/origin/pr/*']]])
+ userRemoteConfigs: [[url: github_url,
+ refspec:
"+refs/heads/${GITHUB_PR_TARGET_BRANCH}:refs/remotes/origin/${GITHUB_PR_TARGET_BRANCH}
+refs/pull/${GITHUB_PR_NUMBER}/head:refs/remotes/origin/pr/${GITHUB_PR_NUMBER}/head
+refs/pull/${GITHUB_PR_NUMBER}/merge:refs/remotes/origin/pr/${GITHUB_PR_NUMBER}/merge"]])
sh '''#!/bin/bash
set -x
diff --git a/jenkins/github/freebsd.pipeline b/jenkins/github/freebsd.pipeline
index 9eddde6..a3aba4d 100644
--- a/jenkins/github/freebsd.pipeline
+++ b/jenkins/github/freebsd.pipeline
@@ -8,6 +8,7 @@ pipeline {
checkout([$class: 'GitSCM',
branches: [[name: sha1]],
extensions: [
+ [$class: 'CloneOption', honorRefspec: true,
timeout: 20],
// We have to set an idenity for the merge step
because Git requires
// the user.name and user.email to be set to do a
merge.
[$class: "UserIdentity",
@@ -23,7 +24,8 @@ pipeline {
]
],
],
- userRemoteConfigs: [[url: github_url, refspec:
'+refs/pull/*:refs/remotes/origin/pr/*']]])
+ userRemoteConfigs: [[url: github_url,
+ refspec:
"+refs/heads/${GITHUB_PR_TARGET_BRANCH}:refs/remotes/origin/${GITHUB_PR_TARGET_BRANCH}
+refs/pull/${GITHUB_PR_NUMBER}/head:refs/remotes/origin/pr/${GITHUB_PR_NUMBER}/head
+refs/pull/${GITHUB_PR_NUMBER}/merge:refs/remotes/origin/pr/${GITHUB_PR_NUMBER}/merge"]])
sh '''#!/bin/bash
set -x
diff --git a/jenkins/github/osx.pipeline b/jenkins/github/osx.pipeline
index 75f8556..8186a18 100644
--- a/jenkins/github/osx.pipeline
+++ b/jenkins/github/osx.pipeline
@@ -8,6 +8,7 @@ pipeline {
checkout([$class: 'GitSCM',
branches: [[name: sha1]],
extensions: [
+ [$class: 'CloneOption', honorRefspec: true,
timeout: 20],
// We have to set an idenity for the merge step
because Git requires
// the user.name and user.email to be set to do a
merge.
[$class: "UserIdentity",
@@ -23,7 +24,8 @@ pipeline {
]
],
],
- userRemoteConfigs: [[url: github_url, refspec:
'+refs/pull/*:refs/remotes/origin/pr/*']]])
+ userRemoteConfigs: [[url: github_url,
+ refspec:
"+refs/heads/${GITHUB_PR_TARGET_BRANCH}:refs/remotes/origin/${GITHUB_PR_TARGET_BRANCH}
+refs/pull/${GITHUB_PR_NUMBER}/head:refs/remotes/origin/pr/${GITHUB_PR_NUMBER}/head
+refs/pull/${GITHUB_PR_NUMBER}/merge:refs/remotes/origin/pr/${GITHUB_PR_NUMBER}/merge"]])
sh '''#!/bin/bash
set -x
diff --git a/jenkins/github/rat.pipeline b/jenkins/github/rat.pipeline
index a8329f8..d271d5c 100644
--- a/jenkins/github/rat.pipeline
+++ b/jenkins/github/rat.pipeline
@@ -16,6 +16,7 @@ pipeline {
checkout([$class: 'GitSCM',
branches: [[name: sha1]],
extensions: [
+ [$class: 'CloneOption', honorRefspec: true,
timeout: 20],
// We have to set an idenity for the merge step
because Git requires
// the user.name and user.email to be set to do a
merge.
[$class: "UserIdentity",
@@ -31,7 +32,8 @@ pipeline {
]
],
],
- userRemoteConfigs: [[url: github_url, refspec:
'+refs/pull/*:refs/remotes/origin/pr/*']]])
+ userRemoteConfigs: [[url: github_url,
+ refspec:
"+refs/heads/${GITHUB_PR_TARGET_BRANCH}:refs/remotes/origin/${GITHUB_PR_TARGET_BRANCH}
+refs/pull/${GITHUB_PR_NUMBER}/head:refs/remotes/origin/pr/${GITHUB_PR_NUMBER}/head
+refs/pull/${GITHUB_PR_NUMBER}/merge:refs/remotes/origin/pr/${GITHUB_PR_NUMBER}/merge"]])
sh '''#!/bin/bash
set -x
diff --git a/jenkins/github/rocky-asan.pipeline
b/jenkins/github/rocky-asan.pipeline
index f8103c5..b6a0037 100644
--- a/jenkins/github/rocky-asan.pipeline
+++ b/jenkins/github/rocky-asan.pipeline
@@ -19,6 +19,7 @@ pipeline {
checkout([$class: 'GitSCM',
branches: [[name: sha1]],
extensions: [
+ [$class: 'CloneOption', honorRefspec: true,
timeout: 20],
// We have to set an idenity for the merge step
because Git requires
// the user.name and user.email to be set to do a
merge.
[$class: "UserIdentity",
@@ -34,7 +35,8 @@ pipeline {
]
],
],
- userRemoteConfigs: [[url: github_url, refspec:
'+refs/pull/*:refs/remotes/origin/pr/*']]])
+ userRemoteConfigs: [[url: github_url,
+ refspec:
"+refs/heads/${GITHUB_PR_TARGET_BRANCH}:refs/remotes/origin/${GITHUB_PR_TARGET_BRANCH}
+refs/pull/${GITHUB_PR_NUMBER}/head:refs/remotes/origin/pr/${GITHUB_PR_NUMBER}/head
+refs/pull/${GITHUB_PR_NUMBER}/merge:refs/remotes/origin/pr/${GITHUB_PR_NUMBER}/merge"]])
sh '''#!/bin/bash
set -x
diff --git a/jenkins/github/rocky.pipeline b/jenkins/github/rocky.pipeline
index 15efdd3..ec6222a 100644
--- a/jenkins/github/rocky.pipeline
+++ b/jenkins/github/rocky.pipeline
@@ -19,6 +19,7 @@ pipeline {
checkout([$class: 'GitSCM',
branches: [[name: sha1]],
extensions: [
+ [$class: 'CloneOption', honorRefspec: true,
timeout: 20],
// We have to set an idenity for the merge step
because Git requires
// the user.name and user.email to be set to do a
merge.
[$class: "UserIdentity",
@@ -34,7 +35,8 @@ pipeline {
]
],
],
- userRemoteConfigs: [[url: github_url, refspec:
'+refs/pull/*:refs/remotes/origin/pr/*']]])
+ userRemoteConfigs: [[url: github_url,
+ refspec:
"+refs/heads/${GITHUB_PR_TARGET_BRANCH}:refs/remotes/origin/${GITHUB_PR_TARGET_BRANCH}
+refs/pull/${GITHUB_PR_NUMBER}/head:refs/remotes/origin/pr/${GITHUB_PR_NUMBER}/head
+refs/pull/${GITHUB_PR_NUMBER}/merge:refs/remotes/origin/pr/${GITHUB_PR_NUMBER}/merge"]])
sh '''#!/bin/bash
set -x
diff --git a/jenkins/github/ubuntu.pipeline b/jenkins/github/ubuntu.pipeline
index 55f2d3f..87b1b02 100644
--- a/jenkins/github/ubuntu.pipeline
+++ b/jenkins/github/ubuntu.pipeline
@@ -19,6 +19,7 @@ pipeline {
checkout([$class: 'GitSCM',
branches: [[name: sha1]],
extensions: [
+ [$class: 'CloneOption', honorRefspec: true,
timeout: 20],
// We have to set an idenity for the merge step
because Git requires
// the user.name and user.email to be set to do a
merge.
[$class: "UserIdentity",
@@ -34,7 +35,8 @@ pipeline {
]
],
],
- userRemoteConfigs: [[url: github_url, refspec:
'+refs/pull/*:refs/remotes/origin/pr/*']]])
+ userRemoteConfigs: [[url: github_url,
+ refspec:
"+refs/heads/${GITHUB_PR_TARGET_BRANCH}:refs/remotes/origin/${GITHUB_PR_TARGET_BRANCH}
+refs/pull/${GITHUB_PR_NUMBER}/head:refs/remotes/origin/pr/${GITHUB_PR_NUMBER}/head
+refs/pull/${GITHUB_PR_NUMBER}/merge:refs/remotes/origin/pr/${GITHUB_PR_NUMBER}/merge"]])
sh '''#!/bin/bash
set -x