GitHub Actions artifact 少了 .env?upload-artifact 的隱藏檔案安全設定
GitHub Actions 的 actions/upload-artifact 找不到 .output、.config 或其他點號開頭的檔案時,先確認 action 目前的預設行為。官方 action 目前預設不會上傳 hidden files;只有明確設定 include-hidden-files: true 才會納入,而且官方要求先檢查這些檔案是否含有敏感資料。
直接答案是:先用明確的 path allowlist 指定需要的產物,再以 include-hidden-files: true 只開啟必要範圍,並用否定 pattern 排除 .env、憑證、.git 和其他不應離開 runner 的檔案。 如果只是要保存一組檔案,也可以先打包成 tar,再上傳單一 archive,讓內容和權限更容易驗證。
為什麼 hidden files 不見了?
從 actions/upload-artifact 的目前文件來看,hidden files 是檔名以 . 開頭的檔案,或位於以 . 開頭資料夾內的檔案;Windows 只有 hidden attribute、但沒有點號前綴的檔案,不會因此被當成 hidden file。action 預設忽略它們,是為了避免意外上傳敏感資訊。
所以先看三件事:
- workflow 實際使用的
actions/upload-artifactmajor 和文件是否一致。 path是否真的涵蓋檔案所在目錄,而不是只指向非隱藏子資料夾。- 檔案是否因前一步建置、清理或
.gitignore之外的工具規則而根本沒有產生。
不要直接把整個 workspace 的 hidden files 都打開。.env、.npmrc、雲端憑證、.git 和 .github 都可能包含不應進 artifact 的內容。
需要隱藏檔案時,先做 allowlist
官方 README 的示範同時開啟 include-hidden-files,並以 path pattern 排除 .production.env。可依自己的產物結構改成更窄的設定:
- name: Upload build output uses: actions/upload-artifact@v7 with: name: build-output include-hidden-files: true if-no-files-found: error path: | dist/ !dist/.env !dist/.env.* !dist/.npmrc !dist/.git/ !dist/.github/這個例子假設 hidden output 確實在 dist/,而不是整個 repository。否定 pattern 要依 action 使用的 glob 行為和實際路徑測試;若產物目錄會被第三方套件寫入,先在 runner 上列出檔名和大小,再決定是否允許上傳。
- name: Inspect artifact files run: | find dist -type f -print if find dist -type f \( -name '.env' -o -name '.npmrc' \) -print -quit | grep -q .; then echo 'Sensitive file found in artifact directory' exit 1 fi檢查步驟不要把檔案內容印到 log;只印路徑、大小或 hash。if-no-files-found: error 也很重要,因為它能讓「原本期待的 hidden output 沒有產生」變成失敗,而不是綠燈後才在下載 artifact 時發現空目錄。
不一定要直接上傳 hidden files
如果 artifact 需要保留一組隱藏檔案與目錄,先建立明確的 tar archive 往往比較容易做內容檢查:
- name: Package selected output run: | tar -cvf build-output.tar -C dist .output .config public
- name: Upload archive uses: actions/upload-artifact@v7 with: name: build-output if-no-files-found: error path: build-output.tar archive: false上傳前仍要檢查 tar 內容:
tar -tf build-output.tar官方文件指出,壓縮 artifact 上傳不會保留原始檔案權限;若要保留 executable bit 和大小寫,先打包 tar,再以單一檔案、archive: false 上傳。這個方法不是安全掃描器,仍要把 .env* 和 credential 檔排除在 tar 建立清單之外。
版本與驗證要一起固定
actions/upload-artifact 的 hidden file 行為在 action 版本演進中曾變更;官方 migration 文件指出,較新的版本預設不再包含 hidden files。不要只在 workflow comment 寫「這裡要上傳 dotfiles」,而要把 action major、allowlist、排除規則與驗證命令放在同一次變更中。
若 workflow 在 GitHub Enterprise Server 上執行,也要先確認 action v4+ 的平台支援限制;GitHub action 官方 README 有列出相容性說明。版本、平台與 artifact 下載端都固定後,再把它接到部署或測試 job,避免不同 runner 對內容有不同期待。
這類產物與 cache 的信任模型不同:cache 只應保存可重建資料,artifact 則應保存明確的 workflow output。若 artifact 會被後續 job 取回執行,接著檢查 GitHub Actions cache 的 restore-keys 安全邊界,不要把兩者都當成可信的檔案倉庫。
常見問題
Q: 為什麼 path: .output 還是找不到檔案?
A: 先確認 action 版本、path 真的指向包含檔案的目錄,以及檔案在 runner 上確實產生。若檔案屬於 hidden file,依目前 action 預設還要設定 include-hidden-files: true;不要用整個 workspace 當 path 來繞過問題。
Q: 所有 workflow 都應該設定 include-hidden-files: true 嗎?
A: 不應該。只有產物需求明確包含 hidden files 時才開啟,並先排除 .env、credential、.git、.github 等敏感或不必要內容。多數 build output 可以用非 hidden allowlist 完成。
Q: 上傳 tar 真的能保留檔案權限嗎?
A: 可以保留在 tar 內的權限資訊,但下載後要先解開 tar 才能取得原始模式。GitHub 文件建議用 tar 作為單一檔案並搭配 archive: false;這仍不會自動替你檢查敏感內容。
參考資料:
回報錯字、失效連結,或告訴我你想看的延伸主題。