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
csv
file.
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
csv
file- 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:
gpr
installed:1
dotnet tool install gpr -g
- Can use this one-liner to find the absolute path for
gpr
for the<path-to-gpr>
parameter:1
find / -wholename "*tools/gpr" 2> /dev/null
<pat>
must havewrite:packages
scope
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
.nupkg
files 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
csv
file.
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
gpr
to 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).
gpr
works because it rewrites the<repository url="..." />
element in the.nuspec
file in the.nupkg
before pushing- There is an item on GitHub’s roadmap to support pushing packages directly to an organization; this should allow
dotnet nuget push
to work instead ofgpr
gpr
still might be preferred since you would have to tie the NuGet package to the repository manually post-migration- For
dotnet nuget push
to 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
gpr
is installed instead of passing in a parameter (right now we are passing thegpr
path in as a parameter explicitly because sometimesgpr
is 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! 📦