GitHub Packages: Migrate NuGet Packages to GitHub Packages
Migrating NuGet packages stored in GitHub Packages from one instance to another
Overview
To complete my NuGet Package migration series, I wanted to demonstrate how one could migrate NuGet packages to GitHub Package. The other system we are migrating from (whether it be Azure Artifacts, Artifactory, etc.) doesn’t so much matter, as long as we are able to download/access the .nupkg files on a system so that we can re-push to GitHub Packages.
See my other NuGet package migration posts:
The script
The repo and docs can be found here:
I decided to store the script in a separate GitHub repo than my github-misc-scripts repo to better facilitate any feedback/suggestions/improvements I might get - feel free to submit a PR if you can improve things 🚀!
Update the mappings file
Your csv file should look something like this:
1
2
3
4
Package,Target GitHub Repo
./mypkg.11.0.1.nupkg,my-org/my-repo
./mypkg.11.0.2.nupkg,my-org/my-repo
Leave a trailing space at the end of the
csvfile.
Running the script
There are two scripts that need to be ran:
- Generate the list of packages to migrate in the current directory and creating a mappings
csvfile- We then need to fill out the GitHub repository mapping for each package in the form of
owner/repo
- We then need to fill out the GitHub repository mapping for each package in the form of
- Migrate the packages to GitHub Packages
Prerequisites
But first, the prequisites:
gprinstalled:1
dotnet tool install gpr -g
- Can use this one-liner to find the absolute path for
gprfor the<path-to-gpr>parameter:1
find / -wholename "*tools/gpr" 2> /dev/null
<pat>must havewrite:packagesscope
We are passing gpr in as a parameter explicitly because sometimes gpr is aliased to git pull --rebase and that’s not what we want here.
Generate the Mappings File
This finds all .nupkg files in the current directory and generates a mappings csv file.
1
2
3
./generate-nuget-package-mappings.sh \
. \
> <mappings-file>
Use this one-liner to copy all
.nupkgfiles to a directory before./generate-nuget-package-mappings.sh:
1 find / -name "*.nupkg" -exec cp "{}" ./ \;
Afterwards, you need to edit the csv file to add the target GitHub repo reference, in the form of owner/repo.
Leave a trailing space at the end of the
csvfile.
Migrate the Packages
This pushes the packages to the mapped GitHub repo:
1
2
3
4
./migrate-nuget-packages-to-github.sh \
<mappings-file> \
<pat> \
<path-to-gpr>
Complete Example
An example of this in practice:
1
2
3
4
5
6
7
8
9
10
11
12
# 1. generate mappings file
./generate-nuget-package-mappings.sh \
. \
> packages.csv
# 2. edit the mappings file to add the GitHub repo in the form of `owner/repo`
# 3. push packages
./migrate-nuget-packages-between-orgs.sh \
packages.csv \
ghp_xyz \
/home/codespace/.dotnet/tools/gpr
Notes
- The script uses
gprto re-push the packages to the target orgI initially tried writing this with
dotnet nuget push, but that doesn’t seem to work since the package’s<RepositoryUrl>element would still be referencing the original repository. See error:1 2 3 4 5 6 7 8 9 10
dotnet nuget push \ -s github \ -k ghp_pat \ NUnit3.DotNetNew.Template_1.7.1.nupkg Pushing NUnit3.DotNetNew.Template_1.7.1.nupkg to 'https://nuget.pkg.github.com/joshjohanning-org-packages-migrated'... PUT https://nuget.pkg.github.com/joshjohanning-org-packages-migrated/ warn : Source owner 'joshjohanning-org-packages-migrated' does not match repo owner 'joshjohanning-org-packages' in repository element. BadRequest https://nuget.pkg.github.com/joshjohanning-org-packages-migrated/ 180ms error: Response status code does not indicate success: 400 (Bad Request).
gprworks because it rewrites the<repository url="..." />element in the.nuspecfile in the.nupkgbefore pushing- There is an item on GitHub’s roadmap to support pushing packages directly to an organization; this should allow
dotnet nuget pushto work instead ofgprgprstill might be preferred since you would have to tie the NuGet package to the repository manually post-migration- For
dotnet nuget pushto work, you will have to add the feed first using this command:1 2 3 4 5 6
dotnet nuget add source \ --username my-github-username \ --password "ghp_pat" \ --store-password-in-clear-text \ --name github \ "https://nuget.pkg.github.com/OWNER/index.json"
Improvement Ideas
- Add a source folder input instead of relying on current directory for
./generate-nuget-package-mappings.sh - Dynamically determine out where
gpris installed instead of passing in a parameter (right now we are passing thegprpath in as a parameter explicitly because sometimesgpris aliased togit pull --rebase)
Summary
Drop a comment here or an issue or PR on the repo if you have any feedback or suggestions! Happy packaging! 📦
