The issue with the Mac slave involved many facets.
First, we were launching the slave with Launch slave agents on Unix machines via SSH. This starts a non-interactive shell to launch the Jenkins slave.jar java process. The fact that this is a not a login shell means that it won't have access to the credentials stored in the keychain without some additional setup. It also means it won't pick up any paths from /etc/paths (used by Homebrew when installing git-lfs) without some bash profile configurations. If we had been launching Jenkins on the slave using Launch slave agents via Java Web Start (which is how our Windows slave was configured) it's possible that we may not have been affected by the access issues (but this wasn't tested).
We had Git LFS installed using Homebrew which modifies /etc/paths to add /usr/local/bin. The paths in this file are loaded by .profile which only gets used for login shells. To add /usr/local/bin to the path (so that git-lfs could be found by the Jenkins slave process) we added a ~/.bashrc file with the modified path.
To enable Git LFS, it was also necessary to modify ~/.gitconfig (using git config --global
) with the following values:
[filter "lfs"]
clean = git-lfs clean %f
smudge = git-lfs smudge %f
required = true
Without this, checkout would succeed but Git LFS would silently not run leaving its stubs in the repository.
It was also necessary to add a credentials helper to the global git configuration (see this link for more details).
[credential]
helper = "osxkeychain "
The Git Plugin uses the slightly weird approach of init+fetch rather than clone to download the repository (see JENKINS-30318 for more details). This was added to work around a credentials issue (which should no longer be necessary). The plugin uses the local git config file (which is why init+fetch was necessary) to temporarily store credentials which are subsequently removed. Specific commands are wrapped with this credentials setup (fetch is one). Unfortunately, the git checkout command was not wrapped with the credentials. This means that when git-lfs is invoked, it must get its credentials from somewhere other than what is stored on Jenkins. From the Git LFS API, it shows that Git LFS can use gitcredentials to access the server (GitHub). On our Windows slave, this just worked. On the Mac slave however, because the Jenkins process was not run in a login shell, Git LFS didn't have permission to access the user keychain and would fail. Opening Keychain Access and moving the keys from the 'Login' category to the 'System' category (see this comment) and allowing all applications to access the key (see this answer), we were finally able to get checkout with Git LFS working.