actions/toolkit

Unix file permissions not stored in zip file

Opened this issue · 1 comments

Describe the bug
Zip files created by upload/zip.ts do not include Unix file permissions. The zip.append method easily allows file permissions to be set by adding a mode argument, whose value is easily available from the Node fs.stat result. This may not be meaningful on Windows runners, but on Unix and OS X runners the file mode, particularly the executable bit, is an important part of the file's metadata and losing it causes issues in many workflows. actions/upload-artifact#38 is a long-requested feature (since 2019!), but the code where that feature actually needs to be fixed is here.

Two changes are necessary to fix this:

To Reproduce
Steps to reproduce the behavior:

  1. Create a workflow running on ubuntu-latest
  2. Have it create an example.sh file and run chmod +x example.sh
  3. Upload example.sh using upload-artifact
  4. Download the resulting artifact on a Linux machine and unzip it using unzip artifact.zip
  5. ls -l example.sh and notice that the executable permission bit has been lost

Expected behavior
The file permissions would be preserved in the .zip file so that they can be extracted with the standard unzip tool on Linux (which preserves file permissions if they are recorded in the .zip file, but cannot "guess" what the permissions should be otherwise). This would partly solve actions/upload-artifact#38; the rest of the solution would involve updating download-artifact.ts to restore the permissions saved in the .zip file.

Screenshots
N/A

Desktop (please complete the following information):

  • OS: Linux
  • Browser: N/A
  • Version: any

Additional context
The .zip file format defines a 4-byte "external file attributes" field for each file, originally used for preserving MS-DOS attributes. The Info-Zip versions of zip and unzip (which have been the standard zip utilities on Linux for over two decades now) use that field to store Unix file modes; see the zipinfo.c file in the source of Info-Zip's unzip implementation for all the details, or https://unix.stackexchange.com/a/14727 for the best easily-available documentation on which bits are where. Most zip-handling tools should be aware of those bits by now, but if you end up needing to implement handling them yourself, those references are the best place to start.

It looks like there's already a PR that would fix this: #1609. It just needs a review from the GitHub Actions team.