linuxgithub-actionsfile-permissionsuser-permissions

Permissions issues when rsync from GitHub Actions


I setup a GitHub Actions workflow which connects to my Linux production machine via SSH using RSA keypair (the setting looks a bit like this tutorial, except I'm trying to create a dedicated Linux user for that, looks to me like it would be the good practice here).

On my Linux machine, I did:

On the GitHub repo side I set up the secrets SSH_PRIVATE_KEY, SSH_HOST and SSH_USER (which is github).

The GitHub Actions workflow file (the interesting steps of the workflow) look like this:

  - name: Install SSH key
    uses: shimataro/ssh-key-action@v2
    with:
      key: ${{ secrets.SSH_PRIVATE_KEY }}
      name: id_rsa
      known_hosts: ${{ secrets.SSH_HOST }}

  - name: Adding known hosts
    run: ssh-keyscan -H ${{ secrets.SSH_HOST }}  >> ~/.ssh/known_hosts

  - name: Copy repository to server with rsync
    run: rsync -avz ./ ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:/home/www/my_project/ --usermap=github:www-data

When I rsync the project folder with the githubuser and its keypair from my local machine project folder to /home/www/my_project/on my production server just for a test, everything works fine.

However, when I push on the repo and the GitHub Actions workflow is executed, the rsync steps fails on many files with the following errors on many files of my project: rsync: [generator] failed to set times on "/home/www/my_project/app/templates/en": Operation not permitted (1)

Why?


Solution

  • After a few tries comparing the permissions of the overwritten files of the server before and after rsync, I found out that the files copied from the repo by GitHub Actions didn't have the group write permission anymore, so it couldn't be written over anymore.

    So we just need to set up the owner, group, files permissions and directory permissions for the copied files when copying, so that they keep the exact same rights that they had before rsync. We set directory (D) and files (F) permissions for group www-data to rwx so that the same users from the www-data group can overwrite later. All in all the rsync step becomes:

    - name: Copy repository to server with rsync
      run: rsync -avz --chown=github:www-data --chmod=Dg=rwx,Fg=rwx ./ ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:/home/www/my_project/
    

    Hope that can be of some help to someone else!

    EDIT 2023/03/01: We might also need to ignore the .git directory to avoid overwriting it, since it would still exist on GitHub's machine even though if it's gitignored. So rsync step becomes:

    - name: Copy repository to server with rsync
      run: rsync -avz --exclude '.git' --chown=github:www-data --chmod=Dg=rwx,Fg=rwx ./ ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:/home/www/my_project/