Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Download Files/Folders from another Repository #1525

Open
steven-pribilinskiy opened this issue Oct 27, 2023 · 8 comments
Open

Download Files/Folders from another Repository #1525

steven-pribilinskiy opened this issue Oct 27, 2023 · 8 comments

Comments

@steven-pribilinskiy
Copy link

steven-pribilinskiy commented Oct 27, 2023

I have a very basic scenario.

      - name: Checkout main repo
        uses: actions/checkout@v4
        with:
          token: ${{ ... }}

      - name: Checkout single file from another repo
        uses: actions/checkout@v4
        with:
          repository: company/repo-name
          ref: main
          token: ${{ ... }}
          clean: false
          sparse-checkout: scripts/some-script.ts
          sparse-checkout-cone-mode: false

And in the output (and using ls) I can see that contents of the repo is always deleted

Run actions/checkout@v4
Syncing repository: company/repo-name
...
Deleting the contents of '/home/runner/work/repo-name/repo-name'

I believe it is a bug or design flaw for this action and missing documentation on this behaviour.

@steven-pribilinskiy
Copy link
Author

Ok, it looks like one must use path to put the content of the repo to another folder.

But that creates the .git folder inside that folder and there's also a need to use mv to move the example script up a level since the script looks have code that looks at relative path ../

@steven-pribilinskiy
Copy link
Author

steven-pribilinskiy commented Oct 27, 2023

I can do something like this:

      - name: Checkout single file
        run: |
          git remote add some-repo https://github.com/company/some-repo.git
          git fetch some-repo main
          git checkout some-repo/main -- scripts/generateActionsDoc.ts

And that works perfectly. These commands interact with the .git folder in the repository where the GitHub Actions runner is executing the workflow, but that's not modifying the current branch or the working directory. The git checkout command checks-out only the specified file into the working directory, leveraging the information stored in the existing .git folder.

So I wonder if we can do the same with the actions/checkout

vvarg229 added a commit to vvarg229/gh-push-allure-report-to-neofs that referenced this issue Jan 21, 2024
Every time actions/checkout is used, all previous context is removed
unless you specify a special flag:
actions/checkout#1525

This causes a bug with empty allure report.
This commit fixes this bug.

Signed-off-by: Oleg Kulachenko <oleg@nspcc.ru>
@moshe-azaria-sage
Copy link

moshe-azaria-sage commented Apr 17, 2024

This is how to do it according to the documentation:

- name: Checkout
  uses: actions/checkout@v4
  with:
    path: main

- name: Checkout private tools
  uses: actions/checkout@v4
  with:
    repository: my-org/my-private-tools
    token: ${{ secrets.GH_PAT }} # `GH_PAT` is a secret that contains your PAT
    path: my-tools

This example is for private repos. For public ones you don't need the token.

@shinebayar-g
Copy link

It looks like it happens when the second checkout tries to use the root directory.

Instead of this

- name: Checkout lib
  uses: actions/checkout@v4
  with:
    repository: owner/repo
    path: lib

- name: Checkout
  uses: actions/checkout@v4

do this

- name: Checkout
  uses: actions/checkout@v4

- name: Checkout lib
  uses: actions/checkout@v4
  with:
    repository: owner/repo
    path: lib

@steven-pribilinskiy
Copy link
Author

steven-pribilinskiy commented Nov 6, 2024

That's exactly the case I was trying to achieve

- name: Checkout
  uses: actions/checkout@v4

- name: Checkout lib
  uses: actions/checkout@v4
  with:
    repository: owner/second-repo
    path: second-repo

The problem with this "official approach" is that this creates the second-repo folder and you might need to do the following if the temporary folder second-repo is not suitable:

  • move files/folders to the root folder
  • delete content of the git repo

So you are ending with two steps

- name: Checkout lib
  uses: actions/checkout@v4
  with:
    repository: owner/second-repo
    path: second-repo

- name: Move my second-repo files
  run: | 
     mv -r !(.*|*.git) ..
     rm -rf second-repo
Explanation:
  • mv -r is an invalid combination of options. The correct option for moving directories is -R or --recursive.
  • !(.*|*.git) is a shell glob pattern that matches all files and directories except for those starting with a dot (.) or ending with .git.
  • .. represents the parent directory.
  • rmdir <folder_name> removes the specified directory if it is empty.
    • <folder_name> should be replaced with the actual name of the folder you want to remove.

So there is this proposed hacky way to use a named remote

      - name: Checkout single file
        run: |
          git remote add some-repo https://github.com/company/some-repo.git
          git fetch some-repo main
          git checkout some-repo/main -- scripts/generateActionsDoc.
Explanation:
  • git remote add some-repo ... adds a new remote repository named some-repo with the specified git repo URL
  • git fetch some-repo main fetches the latest changes from the main branch of the some-repo remote repository.
  • git checkout some-repo/main -- scripts/generate.ts: Checks out the file scripts/generate.ts from the main branch of the some-repo remote repository and updates your working directory with it.

The best part, is that this does not switch branches and it only "downloads" the specified file.

Now this approach has its own flaws of course when it comes to downloading folders. It would look something like that

git sparse-checkout init --cone
git sparse-checkout set <folder-path>
git remote add some-repo https://github.com/company/some-repo.git
git fetch some-repo
git checkout some-repo/main

So for more complex situation a combination of actions/checkout@v4 with bash mv -r ... is preferable.

@steven-pribilinskiy
Copy link
Author

steven-pribilinskiy commented Nov 6, 2024

My point is that this use-case is not well documented and that the action is missing that extra functionality, to easily add (download) files/folders from other repositories into the root folder.

@steven-pribilinskiy
Copy link
Author

Not surprising that ChatGPT Browser suggested the same thing
image

@steven-pribilinskiy
Copy link
Author

steven-pribilinskiy commented Nov 6, 2024

And here is a suggestion to use curl with GitHub API
image

I'm actually switched to curl too. Looks like we think the same way 😅.

It would be nice if actions/checkout could do that effortlessly with support for an array of glob patterns.

Worth adding a ToDo item for the next milestone of the project

@steven-pribilinskiy steven-pribilinskiy changed the title Prevent "Deleting the contents of ..." Download File/Folder from another Repository Nov 6, 2024
@steven-pribilinskiy steven-pribilinskiy changed the title Download File/Folder from another Repository Download Files/Folders from another Repository Nov 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants