# Creating a registry

**URL:** <https://discourse.julialang.org/t/creating-a-registry/12094>\
**Category:** General Usage\
**Tags:** package, tutorials, registry\
**Created:** [July 2, 2018, 12:38am UTC](https://discourse.julialang.org/t/creating-a-registry/12094 "2018-07-02T00:38:13Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![adamslc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adamslc/32/3452_2.png) [@adamslc](https://discourse.julialang.org/u/adamslc)\
**Post date:** [July 2, 2018, 12:38am UTC](https://discourse.julialang.org/t/creating-a-registry/12094/1 "2018-07-02T00:38:13Z")

</div>

I just spend quite a lot of time trying to create a custom registry for the new package manager, so I figured I would document my process so that it goes smoother for the next person.

Our goal is to create a registry `TestRegistry` that contains data about a single package `TestPackage`. We will suppose that `TestPackage` depends on `Example`.

### Creating the package

First we create `TestPackage`, add `Example` as a dependency.

```julia
(v0.7) pkg> generate TestPackage
Generating project TestPackage:
    TestPackage/Project.toml
    TestPackage/src/TestPackage.jl

shell> cd TestPackage

(TestPackage) pkg> add Example
  Updating registry at `~/.julia/registries/TestReg`
  Updating git-repo `/Users/Luke/git/TestReg`
  Updating registry at `~/.julia/registries/Uncurated`
  Updating git-repo `https://github.com/JuliaRegistries/Uncurated.git`
 Resolving package versions...
  Updating `Project.toml`
  [7876af07] + Example v0.5.1
  Updating `Manifest.toml`
  [7876af07] + Example v0.5.1
  [8dfed614] + Test 

```

We will push `TestProject` to some remote repo (Github in this case, but it could be anything in principle). Notice that we add `Manifest.toml` to the `.gitignore` file because we don’t want to make everyone use exactly our configuration.

```julia-auto
cd TestPackage/
git init
echo /Manifest.toml > .gitignore
git add --all
git commit -m 'initial commit'
git remote add origin https://github.com/<username>/TestPackage.jl.git
git push -u origin master

```

### Creating the registry

Now that we have our package, let’s create our registry. Return to your development directory, and create a new directory called `TestRegistry`. Then initialize a git repo.

```julia-auto
mkdir TestRegistry
cd TestRegistry
git init

```

Now that we have created our registry, we need to fill it with the information about our package. Create the following folders and directories:

#### Registry.toml

We can use `UUIDs.uuid1()` to generate a uuid for the registry, and we will need to check `TestPackage`’s `Project.toml` file to find its uuid.

```julia-auto
name = "TestRegistry"
uuid = "f1b7bfcd-108e-44d3-8130-d7177e4bc6a1"
repo = "https://github.com/<user>/TestRegistry.jl.git"
description = "This is only a test."

[packages]
28cd688e-7cf2-11e8-01a0-0dc1d6450aeb = { name = "TestPackage", path = "TestPackage" }

```

#### TestPackage/Package.toml

The `Package.toml` file gives basic data about `TestPackage`. It also specifies where to find the package.

```julia-auto
name = "TestPackage"
uuid = "28cd688e-7cf2-11e8-01a0-0dc1d6450aeb"
author = "<your name here>"
repo = "https://github.com/<user>/TestPackage.jl.git"

```

#### TestPackage/Versions.toml

The `Versions.toml` file gives the git hash associated with every version. To add our first version (v0.1.0), return to the `TestPackage` directory and run `git log` to find the hash of the most recent commit.

```julia-auto
["0.1.0"]
git-tree-sha1 = "3de6e7c41ca27d29cf976d127bf998556441d54d"

```

#### TestPackage/Deps.toml

In `Deps.toml`, we need to specify the name and uuid of the dependencies of `TestPackage`. We can lookup `Example`’s uuid, fill this in.

```julia-auto
["0.1"]
Example = "7876af07-990d-54b4-ab0e-23690620f79a"

```

#### TestPackage/Compat.toml

Finally, `Compat.toml` lists which versions our package is compatible with. Let’s suppose that our package only works with Julia version 0.7, and it can use either `Example` version 0.4 or 0.5.

```julia-auto
["0.1"]
julia = "0.7"
Example = "0.4-0.5"

```

Now we will push all of this data to some remote repo (once again Github).

```julia-auto
git add --all
git commit -m 'initial commit'
git remote add origin https://github.com/<user>/TestRegistry.jl.git
git push -u origin master

```

### Using the registry

Now in `.julia/registries/`, we can clone the registry repo.

```julia-auto
git clone https://github.com/<user>/TestRegistry.jl.git TestRegistry

```

If all has gone well, you should be able to fire up Julia, and add `TestPackage`.

```julia
(v0.7) pkg> add TestPackage
  Updating registry at `~/.julia/registries/TestRegistry`
  Updating git-repo `https://github.com/<user>/TestRegistry.jl.git`
  Updating registry at `~/.julia/registries/Uncurated`
  Updating git-repo `https://github.com/JuliaRegistries/Uncurated.git`
 Resolving package versions...
  Updating `~/.julia/environments/v0.7/Project.toml`
  [28cd688e] + TestPackage v0.1.0
  Updating `~/.julia/environments/v0.7/Manifest.toml`
  [7876af07] + Example v0.5.1
  [28cd688e] + TestPackage v0.1.0
  [8dfed614] + Test 

```

### Upgrading the package

Now suppose that we have added some sweet new features to `TestPackage`, and we would like to publish version 0.1.1. To do this, first edit `Project.toml` to bump the version number, and then commit and push this change.

```julia-auto
vim Project.toml
git add Project.toml
git commit -m 'bump version to 0.1.1'
git push

```

Now we can update some files in `TestRegistry` to make this new version public and accessible to users.

#### TestPackage/Versions.toml

We use the output of `git log` to add a new entry to `Versions.toml`.

```julia-auto
["0.1.0"]
git-tree-sha1 = "3de6e7c41ca27d29cf976d127bf998556441d54d"

["0.1.1"]
git-tree-sha1 = "3c67c429476fb35a1e86b23f7a5662beec2ab894"

```

#### TestPackage/Compat.toml

Let’s suppose that our new changes are not compatible with `Example` version 0.4.

```julia-auto
["0.1"]
julia = "0.7"

["0.1.0"]
Example = "0.4-0.5"

["0.1.1"]
Example = "0.5"

```

Now we can push these updates, and Julia should automatically download the latest version of our registry.

```julia-auto
git add --all
git commit -m "TestPackage v0.1.1"

```

Now we can update TestPackage in Julia.

```julia
(v0.7) pkg> up
  Updating registry at `~/.julia/registries/TestRegistry`
  Updating git-repo `https://github.com/<user>/TestRegistry.jl.git`
  Updating registry at `~/.julia/registries/Uncurated`
  Updating git-repo `https://github.com/JuliaRegistries/Uncurated.git`
 Resolving package versions...
 Installed TestPackage ─ v0.1.1
  Updating `~/.julia/environments/v0.7/Project.toml`
  [28cd688e] ↑ TestPackage v0.1.0 ⇒ v0.1.1
  Updating `~/.julia/environments/v0.7/Manifest.toml`
  [28cd688e] ↑ TestPackage v0.1.0 ⇒ v0.1.1

```

I hope that this write up was helpful to someone. I tried to make it very detailed because I know that I appreciate it when documentation doesn’t make too many assumptions about what I know.

---

<div class="post-metadata">

**Author:** ![Nosferican](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nosferican/32/9275_2.png) [@Nosferican](https://discourse.julialang.org/u/Nosferican)\
**Post date:** [July 3, 2018, 8:55am UTC](https://discourse.julialang.org/t/creating-a-registry/12094/2 "2018-07-03T08:55:41Z")

</div>

I believe the standard UUID version for the packages is UUID4 rather than UUID1, but can’t find the explicit reference in the documentation. Thanks for the basic rundown. If you manage to implement the scripts to update the registry systematically based on the `Project.toml` of a new release that would be great to have.

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [August 20, 2018, 3:30pm UTC](https://discourse.julialang.org/t/creating-a-registry/12094/3 "2018-08-20T15:30:48Z")

</div>

To get the tree-sha, use `git log --pretty=format:'%T %s'` instead of `git log`, which returns the commit SHA.

---

<div class="post-metadata">

**Author:** ![Ward9250](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ward9250/32/42768_2.png) [@Ward9250](https://discourse.julialang.org/u/Ward9250)\
**Post date:** [December 7, 2018, 1:27am UTC](https://discourse.julialang.org/t/creating-a-registry/12094/4 "2018-12-07T01:27:50Z")

</div>

I think they do use uuid1, it’s in the Pkg code currently: [https://github.com/JuliaLang/Pkg.jl/blob/a17e84b1705d6f9e5c2489734b39423a1cc7ca1f/src/generate.jl#L51](https://github.com/JuliaLang/Pkg.jl/blob/a17e84b1705d6f9e5c2489734b39423a1cc7ca1f/src/generate.jl#L51)

---

<div class="post-metadata">

**Author:** ![Nosferican](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nosferican/32/9275_2.png) [@Nosferican](https://discourse.julialang.org/u/Nosferican)\
**Post date:** [December 12, 2018, 10:15pm UTC](https://discourse.julialang.org/t/creating-a-registry/12094/5 "2018-12-12T22:15:25Z")

</div>

UUID4 used to be the default.

> <https://github.com/JuliaLang/Pkg.jl/blob/2075b74621f7829a930a480fe4c3b8c8f8ac0924/src/Operations.jl>

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [December 13, 2018, 12:08am UTC](https://discourse.julialang.org/t/creating-a-registry/12094/6 "2018-12-13T00:08:30Z")

</div>

> [@Nosferican](#):
>
> UUID4 used to be the default.

No? The 4 in the comment there refers to the slug-length.

---

<div class="post-metadata">

**Author:** ![Thuener](https://avatars.discourse-cdn.com/v4/letter/t/7ba0ec/32.png) [@Thuener](https://discourse.julialang.org/u/Thuener)\
**Post date:** [March 29, 2019, 1:27pm UTC](https://discourse.julialang.org/t/creating-a-registry/12094/7 "2019-03-29T13:27:09Z")

</div>

In Julia 1.1 there is some suport on to add registry but create. There is any way to not do this by hand?

---

<div class="post-metadata">

**Author:** ![adamslc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adamslc/32/3452_2.png) [@adamslc](https://discourse.julialang.org/u/adamslc)\
**Post date:** [March 29, 2019, 3:19pm UTC](https://discourse.julialang.org/t/creating-a-registry/12094/8 "2019-03-29T15:19:58Z")

</div>

In short, no there isn’t, and `Pkg` will almost certainly never have that functionality built into it. There are however, some other options. If you are willing to set up some server infrastructure, then [Registrator.jl](https://github.com/JuliaComputing/Registrator.jl) should work for you. If not, then you can try to use [this pull request](https://github.com/JuliaLang/PkgDev.jl/pull/144) for [PkgDev.jl](https://github.com/JuliaLang/PkgDev.jl). Unfortunately, it looks like that PR has recently been closed without merging, which makes the future of small, privately managed registries uncertain.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [March 30, 2019, 1:22pm UTC](https://discourse.julialang.org/t/creating-a-registry/12094/9 "2019-03-30T13:22:59Z")

</div>

There’s every intention to support small registries just not to have that extra functionality built into Pkg, which ships with every copy of Julia, whereas most people don’t need to create registries. As @kristoffer.carlsson indicated when he closed his PR, PkgDev is a legacy package, which is why it’s not being developed further. As he also said: Registrator is the future.

---

<div class="post-metadata">

**Author:** ![adamslc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adamslc/32/3452_2.png) [@adamslc](https://discourse.julialang.org/u/adamslc)\
**Post date:** [March 30, 2019, 3:02pm UTC](https://discourse.julialang.org/t/creating-a-registry/12094/10 "2019-03-30T15:02:50Z")

</div>

My concern is that Registraitor, in its current form, requires too much setup and infrastructure to be usable with small private repositories. I would much prefer something with a PkgDev like workflow. [This issue](https://github.com/JuliaComputing/Registrator.jl/issues/39) is specifically what I’m thinking about.

To be clear, I think Registraitor will be an excellent solution for the General registry, but it doesn’t really scale to my use case well.

---

<div class="post-metadata">

**Author:** ![jpsamaroo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jpsamaroo/32/46804_2.png) [@jpsamaroo](https://discourse.julialang.org/u/jpsamaroo)\
**Post date:** [March 30, 2019, 6:41pm UTC](https://discourse.julialang.org/t/creating-a-registry/12094/11 "2019-03-30T18:41:13Z")

</div>

Can I ask, for my own understanding, what the difficulties with Registrator are in its current form? I haven’t tried setting it up as of yet, but I do plan to do so to add support for another git forge I prefer to use. It would be good to know where the rough edges before I get started 🙂

---

<div class="post-metadata">

**Author:** ![ianfiske](https://avatars.discourse-cdn.com/v4/letter/i/58f4c7/32.png) [@ianfiske](https://discourse.julialang.org/u/ianfiske)\
**Post date:** [April 1, 2019, 1:03pm UTC](https://discourse.julialang.org/t/creating-a-registry/12094/12 "2019-04-01T13:03:34Z")

</div>

My initial concern is that Registrator appears to be Github-specific. If my organization uses another git hosting solution, privately hosted, can we still use some Registrator functions to create/manage a private registry of packages in our git platform?

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [April 1, 2019, 1:43pm UTC](https://discourse.julialang.org/t/creating-a-registry/12094/13 "2019-04-01T13:43:22Z")

</div>

The plan is to support other platforms besides GitHub as well but you’ve got to start somewhere and since most Julia packages are on GitHub currently, that’s the obvious place to start.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [April 1, 2019, 1:45pm UTC](https://discourse.julialang.org/t/creating-a-registry/12094/14 "2019-04-01T13:45:43Z")

</div>

Factoring out the parts of the Registrator code base that would be useful standalone would be a fine project if you want to help contribute to that. What kind of a workflow did you have in mind?

---

<div class="post-metadata">

**Author:** ![ianfiske](https://avatars.discourse-cdn.com/v4/letter/i/58f4c7/32.png) [@ianfiske](https://discourse.julialang.org/u/ianfiske)\
**Post date:** [April 1, 2019, 2:18pm UTC](https://discourse.julialang.org/t/creating-a-registry/12094/15 "2019-04-01T14:18:55Z")

</div>

The Github-first approach totally makes sense given the Julia community’s distribution across platforms.

In the meantime, it seems like the core `register` function ([https://github.com/JuliaComputing/Registrator.jl/blob/master/src/register.jl#L115](https://github.com/JuliaComputing/Registrator.jl/blob/master/src/register.jl#L115)) doesn’t depend on Github. Is there a plan to maintain this separation? If so, we can design around that.

---

<div class="post-metadata">

**Author:** ![adamslc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adamslc/32/3452_2.png) [@adamslc](https://discourse.julialang.org/u/adamslc)\
**Post date:** [April 1, 2019, 3:27pm UTC](https://discourse.julialang.org/t/creating-a-registry/12094/16 "2019-04-01T15:27:23Z")

</div>

I actually spent a few hours this weekend looking into the Registrator internals, and I will hopefully send a PR later this week. This seems like a good workflow:

```julia
julia> using MyPackage, Registrator

julia> Registrator.create_registry("MyRegistry")
Created an empty registry at ~/MyRegistry.

julia> Registrator.register(MyPackage, "~/MyRegistry")
Added package MyPackage.

julia> Registrator.register(MyPackage, "~/MyRegistry")
Error: Version 0.1 of MyPackage is already registered in ~/MyRegistery.
Perhaps you meant to update the version in Project.toml?

```

p.s. I’d like to apologize if I came off as too negative about Registrator.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [April 1, 2019, 6:31pm UTC](https://discourse.julialang.org/t/creating-a-registry/12094/17 "2019-04-01T18:31:21Z")

</div>

Yes, it makes sense to keep it separate. I should probably just extract the part that just takes a new version and makes a new commit to a registry. Seems like that’s the thing people want as a standalone piece.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [April 1, 2019, 6:32pm UTC](https://discourse.julialang.org/t/creating-a-registry/12094/18 "2019-04-01T18:32:43Z")

</div>

Yes that seems good. Do you have any opinion on whether it should be a separate package or just a local API exposed by Registrator?

---

<div class="post-metadata">

**Author:** ![adamslc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adamslc/32/3452_2.png) [@adamslc](https://discourse.julialang.org/u/adamslc)\
**Post date:** [April 2, 2019, 8:47pm UTC](https://discourse.julialang.org/t/creating-a-registry/12094/19 "2019-04-02T20:47:02Z")

</div>

I don’t have a preference either way. I have a draft PR to Registrator [open here](https://github.com/JuliaComputing/Registrator.jl/pull/45), but I’m happy to move the functionality elsewhere if you would prefer.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [April 2, 2019, 8:48pm UTC](https://discourse.julialang.org/t/creating-a-registry/12094/20 "2019-04-02T20:48:35Z")

</div>

Ok, let’s not prematurely over-modularize. We can factor out the API for now and see how that goes. Installing some packages you don’t need isn’t all that horrible in the Pkg3 era.

[Next page](https://discourse.julialang.org/t/creating-a-registry/12094.md?page=2)
