Yesterday I wrote about setting up PHPCS on changed files on CircleCI. Today’s article is about doing the same thing on Codeship Basic.
Code is on the same repository, in the
.codeship folder. You’ll need these two snippets for Setup commands and a Test pipeline:
phpenv local 7.2 # Prepare cache directory and install dependencies mkdir -p ./bootstrap/cache composer install --no-interaction bash $HOME/clone/.codeship/setup.sh
The same logic is used on Codeship as on CircleCI: check out code, get changed files between target branch and PR branch, and run phpcs on those.
The Setup Commands bit sets php to be 7.2 (you can use whatever the latest phpcs supports), creates a bootstrap/cache directory which we don't use, installs composer packages, which is needed to get phpcs in there, and runs our
setup.sh file that’s in the repository.
if [ -d "$HOME/cache/wpcs" ]; then git -C $HOME/cache/wpcs fetch origin && git -C $HOME/cache/wpcs pull origin master else git clone -q -b master https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards.git $HOME/cache/wpcs fi ./vendor/bin/phpcs --config-set installed_paths $HOME/cache/wpcs ./vendor/bin/phpcs -i
$HOME/cache directory is special. It’s retained between builds. If the
wpcs folder is already there, let’s pull down latest master, if it’s not there, let’s check out the coding standards repo at
phpcs (installed via composer) about our new rules, and list them so we can double check.
url="https://api.github.com/repos/$CI_REPO_NAME/pulls/$CI_PR_NUMBER" target_branch=$(curl -s -X GET -G \ $url \ -d access_token=$GITHUB_TOKEN | jq '.base.ref' | tr -d '"') git remote set-branches --add origin $target_branch git fetch origin $target_branch:$target_branch git checkout $target_branch git checkout $CI_BRANCH changed_files=$(git diff --name-only $target_branch..$CI_BRANCH -- '*.php') if [[ -z $changed_files ]] then echo "There are no files to check." exit 0 fi if [ ! -f phpcs.xml ] then echo "No phpcs.xml file found. Nothing to do." exit 0 fi echo "Running phpcs..." ./vendor/bin/phpcs $changed_files
This is mostly the same as the one in CircleCI, adjusted for available environment variables.
Fixing shallow clone
Codeship also does a shallow clone, which implies the use of the
--single-branch flag, which means the remote will only know about that one branch, so a
git fetch will only get info about that one singular branch.
To fix that, we need to tell our local git that we might want to fetch another branch as well. The below achieves this:
git remote set-branches --add origin $target_branch git fetch origin $target_branch:$target_branch
If you look into your
.git/config file, on a normal
git clone you will see this part of the file:
[remote "origin"] url = email@example.com:javorszky/circleci-calibration.git fetch = +refs/heads/*:refs/remotes/origin/*
--single-branch setting, the
fetch will look like this:
fetch = +refs/heads/branch_name:refs/remotes/origin/branch_name
set-branches --add will add a new
fetch entry, so you’ll have this:
fetch = +refs/heads/branch_name:refs/remotes/origin/branch_name fetch = +refs/heads/other_branch_name:refs/remotes/origin/other_branch_name
Once these two lines are there, a
git fetch will get all info on both branches, but only those two branches. Any other branches on the remote will be ignored.
See https://git-scm.com/docs/git-remote.html#Documentation/git-remote.txt-emset-branchesem for official git documentation.
Grabbing the difference
Now that we have both the feature and target branch in our fetch config, git can pull info from both, which means we can check out both, and the
git diff will return a meaningful list of files.
Don’t forget to check out the feature branch again after checking out the target branch.
git diff will definitely get you the list of files changed in the PR, but if you’re still on the target branch, it will run phpcs on those files as they were before you began work. Which means the files might not even exist.
Other than that, this is all that should be needed.