10

I have a folder named "public" containing subfolders (with subfolders and files, and so on) and files like:

└ public
  └ folder1
     └ file1.txt
  └ folder2
   p_file1.txt
   p_file2.txt

These folders and files should be returned as artifact from a gitlab runners run. So long that works but also the folder "public" is getting part of the zip file as parent folder to the others. I only want to get the subfolders and files into the zip file without their parent folder "public" (replace "public" in the above example but "artifact.zip" for the intended structure).

So far I tried:

- "public"
- "public/*"
- "public/**"
- "public/**/*"

Edit (I was maybe not that clear): I would like to specify it within gitlab-ci.yml:

  artifacts:
    name: app
    paths:
      - ???
AnnetteC
  • 490
  • 2
  • 5
  • 20
  • An issue has been opened about that [on the GitLab-CI project](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/1057) in 2016. As of the writing of this comment (2023, 7 years after), the issue is still under heavy development. Until the issue is closed, you can only find workarounds, but you may soon have a keyword for that in your `.gitlab-ci.yml` file! – SteeveDroz Apr 26 '23 at 05:35

1 Answers1

10

When GitLab collects artifacts, the relative path within the zip archive will always match the relative path from which they are collected in the workspace, irrespective of what paths: rule was used to match the file.

The paths: and exclude: patterns simply determine which files are included.

From the docs:

The paths keyword determines which files to add to the job artifacts. All paths to files and directories are relative to the repository where the job was created.

In order to get the artifacts to appear in the order you want, you'll have to arrange them how you want relative to the working directory. For example using mv ./public/subdir ./subdir in your job then a matching rule to artifact ./subdir.

e.g.

my_job:
  # ...
  after_script:
    - mv public/subdir ./subdir
  artifacts:
    paths:
      - subdir

If getting the rules to match is difficult (for example, if you want to use glob patterns that would otherwise match files in your repo), you could consider either using artifacts:untracked or a standalone job for rearranging artifacts from the previous job's artifacts.

For example, suppose you wanted to match all files under public containing html files, but you wanted subdirectories under public to be at the top-level of your artifact distribution. However you (1) don't know what subdirectories will exist ahead of time and (2) glob patterns in the root may match files in your repo and (3) you can't reasonably add exclude: rules to prevent artifacting of unwanted files that may exist in your repository. -- you can use one of the following strategies:

Move the files to the workspace root (or however you want them arranged) and use artifacts:untracked

my_job:
  after_script:
    - mv ./public/* ./  # move subdirs and files to root
      # or however you want them arranged in your artifact archive,
      # relative to the workspace root
    - rm -rf ./public
  artifacts:
    untracked: true  # artifact everything not tracked by git

Use a secondary job to re-arrange your artifacts

stages:
  - one
  - two
my_job:
  stage: one
  # ...
  artifacts:
    paths:
      - public/**/*.html
    expire_in: "1h"  # optionally, expire these quickly

rearrange_artifacts:
  stage: two
  needs: [my_job]  # only restore artifacts from this job, start right away
  variables:
    GIT_STRATEGY: none # prevent repository checkout, optional
  script:
    - mv public/* ./  # move subdirectories and files to root
    - rm -rf ./public
  artifacts:
    untracked: true  # artifact everything, excluding git-tracked files
    ## or; artifact the workspace dir, including git tracked files
    # paths:
    #   - $CI_PROJECT_DIR
sytech
  • 29,298
  • 3
  • 45
  • 86