diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index c53e153e423c090c0b7babb168208883e56869b3..f0de97fbda57d543d8f9f4ee983da12aa7bbe46b 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -27,6 +27,11 @@ variables:
   # Default GHC bindist
   GHC_TARBALL: "https://gitlab.haskell.org/api/v4/projects/1/jobs/artifacts/master/raw/ghc-x86_64-fedora27-linux.tar.xz?job=validate-x86_64-linux-fedora27"
 
+  # Default this to ghc/ghc> to make it more convenient to run from the web
+  # interface.
+  UPSTREAM_PROJECT_ID: 1
+  UPSTREAM_PROJECT_PATH: "ghc/ghc"
+
   # CPUS is set by the runner, as usual.
 
   # EXTRA_HC_OPTS are passed to via --ghc-options to GHC during the package
@@ -42,6 +47,10 @@ variables:
   # These are set by the "upstream" pipeline for `build-pipeline` pipelines:
   #
   #   UPSTREAM_PROJECT_PATH: The path of the upstream project (e.g. `ghc/ghc`)
+  #   UPSTREAM_PIPELINE_ID: The ID of the upstream pipeline
+  #
+  # Instead of UPSTREAM_PIPELINE_ID you can also pass:
+
   #   UPSTREAM_COMMIT_SHA: The ref or commit SHA of the GHC build to be tested
   #
 
@@ -52,11 +61,23 @@ build-pipeline:
   before_script:
     - |
       if [ -n "$UPSTREAM_COMMIT_SHA" ]; then
+        # N.B. We can't use this if the upstream pipeline might be in-progress
+        # since the below URL cannot provide an artifact until a pipeline has
+        # run to completion on the requested branch. This is in general
+        # not the case for GHC pipelines. Consequently, in this case we will
+        # usually rather provide UPSTREAM_PIPELINE_ID.
         echo "Pulling binary distribution from commit $UPSTREAM_COMMIT_SHA of project $UPSTREAM_PROJECT_PATH..."
         GHC_TARBALL="https://gitlab.haskell.org/$UPSTREAM_PROJECT_PATH/-/jobs/artifacts/$UPSTREAM_COMMIT_SHA/raw/ghc-x86_64-fedora27-linux.tar.xz?job=validate-x86_64-linux-fedora27"
+      elif [ -n "$UPSTREAM_PIPELINE_ID" ]; then
+        job_name="validate-x86_64-linux-fedora27"
+        echo "Pulling ${job_name} binary distribution from Pipeline $UPSTREAM_PIPELINE_ID..."
+        job_id=$(nix run -f ci/default.nix \
+          -c find-job $UPSTREAM_PROJECT_ID $UPSTREAM_PIPELINE_ID $job_name)
+        echo "Using job $job_id..."
+        GHC_TARBALL="https://gitlab.haskell.org/$UPSTREAM_PROJECT_PATH/-/jobs/$job_id/artifacts/raw/ghc-x86_64-fedora27-linux.tar.xz"
       fi
   rules:
-    - if: '$UPSTREAM_COMMIT_SHA'
+    - if: '$UPSTREAM_COMMIT_SHA || $UPSTREAM_PIPELINE_ID'
       when: always
     - when: never
 
@@ -67,7 +88,7 @@ build-master:
     GHC_TARBALL: "https://gitlab.haskell.org/api/v4/projects/1/jobs/artifacts/master/raw/ghc-x86_64-fedora27-linux.tar.xz?job=validate-x86_64-linux-fedora27"
     EXTRA_HC_OPTS: "-dcore-lint -ddump-timings"
   rules:
-    - if: '$UPSTREAM_COMMIT_SHA'
+    - if: '$UPSTREAM_COMMIT_SHA || $UPSTREAM_PIPELINE_ID'
       when: never
     - when: always
 
@@ -78,7 +99,7 @@ build-9.0:
     GHC_TARBALL: "https://gitlab.haskell.org/api/v4/projects/1/jobs/artifacts/ghc-9.0/raw/ghc-x86_64-fedora27-linux.tar.xz?job=validate-x86_64-linux-fedora27"
     EXTRA_HC_OPTS: "-dcore-lint"
   rules:
-    - if: '$UPSTREAM_COMMIT_SHA'
+    - if: '$UPSTREAM_COMMIT_SHA || $UPSTREAM_PIPELINE_ID'
       when: never
     - when: always
 
@@ -89,7 +110,7 @@ build-9.2:
     GHC_TARBALL: "https://gitlab.haskell.org/api/v4/projects/1/jobs/artifacts/ghc-9.2/raw/ghc-x86_64-fedora27-linux.tar.xz?job=validate-x86_64-linux-fedora27"
     EXTRA_HC_OPTS: "-dcore-lint"
   rules:
-    - if: '$UPSTREAM_COMMIT_SHA'
+    - if: '$UPSTREAM_COMMIT_SHA || $UPSTREAM_PIPELINE_ID'
       when: never
     - when: always
 
diff --git a/ci/default.nix b/ci/default.nix
index 5f1eab67a7981ad2383587f9d03123b3d5bf56e5..f0ec34c492157ed876f3b053fae2173494bd49ef 100644
--- a/ci/default.nix
+++ b/ci/default.nix
@@ -67,6 +67,9 @@ let
             --set USE_NIX 1 \
             --set CI_CONFIG ${./config.sh}
 
+        makeWrapper ${./find-job.sh} $out/bin/find-job \
+            --prefix PATH : ${stdenv.lib.makeBinPath deps}:$out/bin
+
         makeWrapper ${xz}/bin/xz $out/bin/xz
         makeWrapper ${curl}/bin/curl $out/bin/curl
       '';
diff --git a/ci/find-job.sh b/ci/find-job.sh
new file mode 100755
index 0000000000000000000000000000000000000000..dc4165238c75c20e599522892c62e5bcecef264e
--- /dev/null
+++ b/ci/find-job.sh
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+
+set -e
+
+project_id=$1
+pipeline_id=$2
+job_name=$3
+
+# Access token is a protected environment variable in the head.hackage project and
+# is necessary for this query to succeed. Sadly job tokens only seem to
+# give us access to the project being built.
+curl \
+  --silent --show-error \
+  -H "Private-Token: $ACCESS_TOKEN" \
+  "https://gitlab.haskell.org/api/v4/projects/$project_id/pipelines/$pipeline_id/jobs?scope[]=success" \
+  > resp.json
+
+job_id=$(jq ". | map(select(.name == \"$job_name\")) | .[0].id" < resp.json)
+if [ "$job_id" = "null" ]; then
+  echo "Error finding job $job_name for $pipeline_id in project $project_id:" >&2
+  cat resp.json >&2
+  rm resp.json
+  exit 1
+else
+  rm resp.json
+  echo -n "$job_id"
+fi