Git clone fails when running CI on private fork (solution)

Continuing the discussion from Git clone fails when running CI on private fork:

I wanted to contribute with the solution I found for allowing forks from a private repo without exposing all your keys, its mostly a copy of the original checkout script just forcing the right setup of a new deployment key.

Note that the deployment key MUST NOT HAVE WRITE access because you are copying it in plain text in your config.

checkout_repo: &checkout_repo
  run:
  name: Custom checkout
  # We need this to allow forks from a private repo
  # We can remove this job once the repo is public
  command: |
  # Add GitHub to known hosts.
  mkdir -p ~/.ssh
  echo 'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==' >> ~/.ssh/known_hosts

  # Prepare SSL deploy cert
  (umask 077; touch ~/.ssh/id_rsa)
  chmod 0600 ~/.ssh/id_rsa

  # Private key (this is write only for deployment is fine to expose it)
  echo "(private key in base 64 here to avoid newlines)" | base64 --decode > ~/.ssh/id_rsa

  # Public key (doesn't work without this - git somehow needs it)
  echo "ssh-rsa [public key here...]" > ~/.ssh/id_rsa.pub

  # SSH Config
  (cat <<EOF > ~/.ssh/config
  Host github.com
  HostName github.com
  IdentityFile ~/.ssh/id_rsa
  User git
  EOF
  )

  # Add key to the daemon
  ssh-add ~/.ssh/id_rsa

  # use git+ssh instead of https
  git config --global url."ssh://git@github.com".insteadOf "https://github.com" || true
  git config --global gc.auto 0 || true

  if [ -e /home/circleci/lwc/.git ]
  then
    cd /home/circleci/lwc
    git remote set-url origin "$CIRCLE_REPOSITORY_URL" || true
  else
    mkdir -p /home/circleci/lwc
    cd /home/circleci/lwc
    git clone "$CIRCLE_REPOSITORY_URL" .
  fi

  if [ -n "$CIRCLE_TAG" ]
  then
    git fetch --force origin "refs/tags/${CIRCLE_TAG}"
  else
    git fetch --force origin "${CIRCLE_BRANCH}/head:remotes/origin/${CIRCLE_BRANCH}"
  fi


  if [ -n "$CIRCLE_TAG" ]
  then
    git reset --hard "$CIRCLE_SHA1"
    git checkout -q "$CIRCLE_TAG"
  elif [ -n "$CIRCLE_BRANCH" ]
  then
    git reset --hard "$CIRCLE_SHA1"
    git checkout -q -B "$CIRCLE_BRANCH"
  fi

  git reset --hard "$CIRCLE_SHA1"
2 Likes

Thanks for sharing, Diego!

I recommend using an ENV and https://circleci.com/docs/2.0/configuration-reference/#add_ssh_keys, instead of putting your key in your config.

That would not work for the use case since secrets are not passed to the forked pr. Or am I misunderstanding?

Ah, no, you are correct. My brain skipped over the fork part. :frowning:

You can share the secrets, you just want to be careful when doing so. Since it’s private it’s probably safe, since only folks you trust can fork.

https://circleci.com/:vcs-type/:org/:repo/edit#advanced-settings