Run a script from the repo
Run a repository script from a workflow with run: ./script.sh only if Git stores it as executable. Otherwise the step fails with Permission denied, status 126.
A script runs fine on your Mac and the workflow stops with "Permission denied" on the first line that calls it.
git init -q repo && cd repo
printf '#!/bin/sh\necho "deploying"\n' > deploy.sh
chmod -x deploy.sh
git add deploy.sh
git ls-files -s deploy.sh | cut -d' ' -f1
git -c user.name=t -c user.email=t@t commit -qm "add deploy"
git clone -q . ../runner && cd ../runner
./deploy.sh; echo "status $?"
cd ../repo
git update-index --chmod=+x deploy.sh
git ls-files -s deploy.sh | cut -d' ' -f1
git -c user.name=t -c user.email=t@t commit -qm "make deploy executable"
git clone -q . ../runner2 && cd ../runner2
./deploy.sh; echo "status $?"100644
bash: line 8: ./deploy.sh: Permission denied
status 126
100755
deploying
status 0Git records only one permission bit, the executable flag, as mode 100755 or 100644. A runner checks the repository out fresh, so a script that was committed with 100644 is not executable there, and calling it directly fails with status 126. git update-index --chmod=+x sets the flag in the index regardless of the local file system, which matters on Windows. The modes are listed in the git-update-index manual.
run: bash deploy.sh avoids the issue, since the file only has to be readable, and it also sets the interpreter explicitly. Check git ls-files -s before pushing a script that someone created on Windows, or in a ZIP. Scripts called from a Docker action or a different checkout path have the same rule.