actions / actions/toolkit

Unix file permissions not stored in zip file

Open
#1,722 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
TypeScript
Stars
5.9k
Forks
1.8k
PR merge metrics
No merged PRs in 30d

Description

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. https://github.com/actions/upload-artifact/issues/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 https://github.com/actions/upload-artifact/issues/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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with packages/artifact/src/internal/upload/upload-zip-specification.ts and packages/artifact/src/internal/upload/zip.ts, then follow the fs.stat result and zip.append call described in the issue. Reproduce with an executable example.sh on Ubuntu and inspect the extracted file with ls -l. Done means the ZIP records the Unix mode so standard unzip preserves the executable bit.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, typescript
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.