Skip to content

Instantly share code, notes, and snippets.

@DeliciousKokas
Last active June 13, 2023 01:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save DeliciousKokas/f3907bd7ab2353670f457845d4fe4239 to your computer and use it in GitHub Desktop.
Save DeliciousKokas/f3907bd7ab2353670f457845d4fe4239 to your computer and use it in GitHub Desktop.

Tweak your CircleCI server to build forked PRs even if the fork has an active CircleCI project

Overview

This instruction consists of 2 parts:

  1. Apply a patch to examine the special project flag.

  2. Set a special flag for projects which should run pipelines for every forked PRs.

    Note: Run this step for all the original projects which has forks.

    For example, assuming there are following projects:

    * `org-a/project-x`
    * `org-a/project-y`
    * `user-k/project-x` (fork of `org-a/project-x`)
    * `user-l/project-x` (fork of `org-a/project-x`)
    * `user-m/project-y` (fork of `org-a/project-y`)
    * `user-n/project-y` (fork of `org-a/project-y`)
    

    please run this instruction 2 times: for org-a/project-x and org-a/project-y.

Step 1: Apply a patch to examine the special project flag

Run the following shell script on a machine with kubectl being capable of communicating with you K8s cluster hosting CircleCI:

#!/bin/bash

# YOUR_PRIVATE_IP_ADDRESS - IP address of your computer running this script
# If you are running this script on non-Linux environment you will need to modify it accordingly
YOUR_PRIVATE_IP_ADDRESS="$(ip -4 route get 192.0.2.1 | grep -oP 'src \S+' | awk '{ print $2 }')"

# Port forward nREPL for frontend
kubectl port-forward "$(kubectl get po -l app=frontend -n circleci-server -o jsonpath='{.items[0].metadata.name}')" --address "${YOUR_PRIVATE_IP_ADDRESS}" 6005 -n circleci-server &

# Start nREPL and apply the patch there
sudo docker run --rm -i clojure lein repl :connect "${YOUR_PRIVATE_IP_ADDRESS}":6005 <<EOD
(ns circle.http.pull-requests.github)
(defn- should-build-from-pr-with-explanation [action head-proj base-proj]
  (let [fork-pr? (not= (:_id head-proj)
                       (:_id base-proj))]
    (cond
      (and (not fork-pr?)
           (feature/build-prs-only base-proj)
           (contains? #{"opened" "synchronize" "reopened"} action))
      [true "yes: project only builds from PRs"]

      (and fork-pr?
           (->> base-proj :features :always-build-fork-prs))
      [true "yes: always-build-fork-prs feature is set for the project"]

      (and fork-pr?
           (project/configured-to-build? head-proj))
      [false "no: fork is followed"]

      (and (not (project/oss? base-proj))
           (not (feature/build-fork-prs base-proj)))
      [false "no: private project without flag set"]

      (and fork-pr?
           (feature/build-fork-prs base-proj))
      [true "yes: flag set"]

      :else
      [false "no: feature not set"])))
EOD

# Close the forwarding port
kill $!

Step 2: Set a special flag for projects which should run pipelines for every forked PRs

For each project of interest run the following command on a machine with kubectl being capable of communicating with you K8s cluster hosting CircleCI (replace the part org-a/project-x with an actual project name accordingly):

kubectl exec -i "$(kubectl get po -l app=frontend -n circleci-server -o jsonpath='{.items[0].metadata.name}')" -n circleci-server -- lein repl :connect 6005 <<EOD
(circle.http.api.admin-commands/set-project-feature-by-url-unsafe "gh/org-a/project-x" :always-build-fork-prs)
EOD
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment