Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

276 linesCodeBlameRaw
1---
2title: Packages
3description: Publish and install packages beside your code, with the same people, roles and tokens.
4---
5
6A workspace can publish packages to g1t and install them from it, beside
7the code they are built from: container images, npm packages, Rust
8crates, Maven artifacts, NuGet packages, Ruby gems, Composer packages and
9Go modules. Each registry speaks its tool's own protocol, so `docker`,
10`npm`, `cargo`, `mvn` and Gradle, `dotnet`, `gem` and Bundler, `composer`
11and `go` work with nothing but a login and an address. Composer packages and Go modules are
12read from the workspace's repositories: there is nothing to upload.
13
14| Registry | Address | Guide |
15| --- | --- | --- |
16| Container images | `g1t.sh/<workspace>/<name>` | [Container images](/guides/containers/) |
17| npm | `https://g1t.sh/-/npm/`, for the scope `@<workspace>` | [npm](/guides/npm/) |
18| Cargo | `sparse+https://g1t.sh/-/cargo/<workspace>/index/`, a registry per workspace | [Cargo](/guides/cargo/) |
19| Maven | `https://g1t.sh/-/maven/<workspace>/`, a repository per workspace, for Maven and Gradle | [Maven](/guides/maven/) |
20| NuGet | `https://g1t.sh/-/nuget/<workspace>/v3/index.json`, a feed per workspace, with a symbol server | [NuGet](/guides/nuget/) |
21| RubyGems | `https://g1t.sh/-/rubygems/<workspace>/`, a registry per workspace, for `gem push`, `gem install` and Bundler | [RubyGems](/guides/rubygems/) |
22| Composer | `https://g1t.sh/-/composer/<workspace>/`, from the workspace's repositories | [Composer](/guides/composer/) |
23| Go | `g1t.sh/<workspace>/<repo>`, straight from git | [Go modules](/guides/go/) |
24
25## Names
26
27Every package's name starts with its workspace: `g1t.sh/acme/web` is the
28`web` image of the `acme` workspace. A name may have more parts after it,
29such as `g1t.sh/acme/web/worker`.
30
31## Who can see and publish a package
32
33Everyone has one role on a package, the highest of what reaches them:
34
35| Role | Lets them |
36| --- | --- |
37| Read | Pull and install it. Anyone, signed in or not, may on a public package. |
38| Write | Also publish new versions and tags. |
39| Admin | Also delete and restore it and its versions, and change its [settings](#package-settings). |
40
41A package is linked to a repository, or belongs to its workspace, and that
42decides where its roles come from:
43
44- **Linked.** The first push of an image whose name starts with a
45 repository's name (`acme/web`, `acme/web/worker` for the repository
46 `acme/web`) links it to that repository, unless its
47 [source label](/guides/containers/#link-an-image-with-its-source-label)
48 names another; so does the first publish of an npm package whose
49 `package.json` `repository` is a g1t.sh repository of the workspace, or
50 which is named like one (`@acme/web`), and of a crate whose `Cargo.toml`
51 `repository` is one, or which is named like one. Maven artifacts (by
52 artifactId, or the POM's `<scm><url>`), NuGet packages (by
53 `RepositoryUrl`, or their id) and gems (by `source_code_uri`, or their
54 name) are linked the same way. It has the repository's visibility and,
55 while it **inherits access** (the default), its
56 [roles](/guides/access-and-roles/): Read and Triage pull, Write and
57 Maintain publish, Admin administers.
58- **Unlinked.** A package whose name matches no repository is the
59 workspace's. It is private: members pull and push it by the workspace's
60 [base permission](/guides/access-and-roles/#the-base-permission) (Read pulls,
61 Write pushes), and an Admin base permission still only pushes. An admin
62 can make it public, and then anyone can pull it.
63
64On top of that:
65
66- **The workspace's owners** are admins of every package.
67- **People and teams given a role on the package itself**, under
68 [Manage access](#manage-access), have that role, or the one their
69 repository or base permission gives them if it is higher. A team's role
70 reaches its child teams' people too.
71- **Turning off inheriting** on a linked package leaves only the roles
72 given on the package itself, and the workspace's owners: the
73 repository's roles no longer reach it. Its visibility is still the
74 repository's.
75
76Private packages look exactly like ones that do not exist to anyone who may
77not pull them.
78
79## Package settings
80
81A package's admins see a **Settings** tab on its page, at
82`g1t.sh/<workspace>/-/packages/<type>/<name>?tab=settings`:
83
84| Setting | What it does |
85| --- | --- |
86| Inherit access from the linked repository | On (the default), the repository's roles reach the package. Off, only the roles below and the workspace's owners do. Linked packages only. |
87| Manage access | People (by username) and teams of the workspace (by slug), each with the Read, Write or Admin role on the package. |
88| Manage Actions access | The repositories whose workflows may use the package, each with Read or Write. See [below](#manage-actions-access). |
89| Visibility | Public or private, for an unlinked package. A linked one has its repository's. |
90| Repository | Link it to a repository of its workspace (Admin on that repository is needed too), or unlink it: it is then the workspace's, and private. |
91| Deleted versions | Versions deleted in the last 30 days, each with **Restore**. |
92| Delete this package | Delete it, with every version. See [deleting and restoring](#delete-and-restore). |
93
94### Manage access
95
96Add a person by username, or a team of the workspace by its slug, with a
97role; change a role from its row, or remove it. What a repository or the
98workspace gives someone stays when the package's own role is removed.
99
100### Manage Actions access
101
102A workflow job's [`G1T_TOKEN`](/guides/actions/#the-jobs-token) reaches a
103package only from these repositories:
104
105| Repository | Its workflows may |
106| --- | --- |
107| The one the package is linked to | Pull and publish it, always. It is listed, and cannot be removed: unlink the package instead. |
108| One added with Read | Pull it |
109| One added with Write | Pull and publish it |
110| Any other | Nothing: the job is refused, with a message naming the package and saying to add its repository here. A public package still pulls. |
111
112A package a workflow job makes that is not linked to the job's repository
113(a workspace package, say `g1t.sh/acme/tools` pushed from `acme/web`) is
114given its repository with Write, so the workflow that made it keeps
115publishing it. The job's token is still held to the job's own
116`permissions:`, never deletes a package and never changes its settings.
117
118## Delete and restore
119
120Deleting a package, or one version, hides it from every registry at once:
121pulls and installs get "not found", as for one that never existed. It is
122kept for **30 days**, and until then:
123
124- An admin of the package can restore it: a version from the package's
125 **Settings → Deleted versions**, a package from **Deleted packages** on
126 the workspace's Packages page (`g1t.sh/<workspace>/-/packages?view=deleted`),
127 listed for whoever administers it. A restored version comes back with
128 the tags that still pointed to it.
129- A deleted package's name stays taken: nobody can publish a package of
130 that name in the workspace. A deleted version's version (for a container
131 image, its digest) cannot be published again.
132- Its files are kept, and do not count toward the workspace's storage.
133
134After 30 days it is purged for good, and files nothing else uses are
135removed a day later. Composer versions follow their repository's tags and
136branches, so they are deleted there, not here.
137
138Deleting through a registry's own protocol (`docker` and the OCI `DELETE`,
139`npm unpublish`) works the same way.
140
141## Tokens
142
143Sign in to a registry with your username and an
144[access token](/guides/authentication/#access-tokens) as the password.
145A token with scopes needs the package ones:
146
147| Scope | Lets a token |
148| --- | --- |
149| `packages:read` | Pull private packages. Public ones need no scope. |
150| `packages:write` | Push and publish. Includes `packages:read`. |
151| `packages:delete` | Delete and restore versions and packages |
152
153Tokens with full access, and tokens made before scopes, have all three.
154Changing a package's settings needs `packages:write` and the Admin role on
155it. A token never does more than its owner could: `packages:delete` alone
156does not let a member delete an owner's package.
157
158| Token | Reaches |
159| --- | --- |
160| A personal access token for all your workspaces | What its owner may do, limited by its permissions. |
161| A personal access token for one workspace | Packages linked to a repository in its selection, and the unlinked packages of its workspace. Elsewhere it pulls public packages only. |
162| A workspace's own token | The workspace's packages, as a member with Write; with Admin when it has Repositories: admin. With selected repositories, linked packages of those only. |
163| A workflow job's `G1T_TOKEN` | Its own repository's packages, and those that list its repository under [Manage Actions access](#manage-actions-access), as the job's `permissions:` allow. |
164| A deploy key | No packages. |
165
166In [workflows](/guides/actions/#the-jobs-token), `G1T_TOKEN` is the job's
167own token: it pushes and pulls its repository's packages with no setup, and
168any other package once its admins add the repository under Manage Actions
169access.
170
171## Storage
172
173Every file is kept once, by its content: two images that share a layer
174store it once, and a layer pushed again is not stored again. A workspace's
175storage counts each file once, as public when any public package uses it.
176
177Files no version uses any more are deleted a day after the last version
178that used them goes.
179
180Without the [g1t plan](/guides/usage-and-billing/#the-g1t-plan), public
181packages may hold 10 GB and private ones 500 MB per workspace; a push past
182either is refused, with a message saying how much is used. On the plan,
183nothing is refused and storage past those amounts is charged instead:
184
185- What the workspace's packages hold is measured each day, public and
186 private apart, each past its own free amount.
187- A month's GB-months are those days added up, divided by the days in the month, charged at
188 $0.018 a GB-month as **Package storage** on the
189 [bill](/guides/usage-and-billing/).
190- Deleted packages and versions, kept for 30 days, do not count.
191- Downloads and pulls cost nothing. Anonymous pulls are rate limited; see
192 [storage and pull limits](/guides/containers/#storage-and-pull-limits).
193
194## Downloads
195
196Each package's page shows its pulls or downloads, and each version's own,
197counted approximately: an image's manifest fetched by tag or digest, an npm
198tarball, a crate, a Maven artifact (not its POM or signatures), a NuGet
199`.nupkg`, a gem, and a Composer zip.
200
201A package's files are its publisher's, so the registries never let a
202browser run them. Every registry answer carries
203`X-Content-Type-Options: nosniff` and
204`Content-Security-Policy: default-src 'none'; sandbox`, and a file a
205browser would open as a page, such as a POM, a `.nuspec` or anything else
206in XML, HTML or SVG, comes with `Content-Disposition: attachment`, so it
207downloads instead. Package managers ignore these headers.
208
209## The API
210
211The [REST API](/reference/api/) and the `package` tool of the
212[MCP server](/reference/mcp/) manage packages. A package is named by its
213type (`container`, `npm`, `cargo`, `maven`, `nuget`, `rubygems` or
214`composer`) and its name, URL-encoded where it holds a slash
215(`web%2Fworker`):
216
217| Route | Operation | Scope |
218| --- | --- | --- |
219| `GET /workspaces/{workspace}/packages` | `list_packages` (`state=deleted` for deleted ones) | `packages:read` |
220| `GET /workspaces/{workspace}/packages/{package_type}/{package_name}` | `get_package` | `packages:read` |
221| `PATCH …/{package_name}` | `update_package`: `visibility`, `inherit_access` | `packages:write` |
222| `DELETE …/{package_name}` | `delete_package` | `packages:delete` |
223| `POST …/{package_name}/restore` | `restore_package` | `packages:delete` |
224| `GET …/{package_name}/versions` | `list_package_versions` (`state=deleted` for deleted ones) | `packages:read` |
225| `GET …/versions/{version_id}` | `get_package_version` | `packages:read` |
226| `DELETE …/versions/{version_id}` | `delete_package_version` | `packages:delete` |
227| `POST …/versions/{version_id}/restore` | `restore_package_version` | `packages:delete` |
228| `PUT …/{package_name}/repository` | `link_package` | `packages:write` |
229| `DELETE …/{package_name}/repository` | `unlink_package` | `packages:write` |
230| `GET …/{package_name}/access` | `list_package_access` | `packages:read` |
231| `PUT …/{package_name}/access` | `set_package_access`: `username` or `team`, and `role` | `packages:write` |
232| `DELETE …/{package_name}/access?username=…` or `?team=…` | `remove_package_access` | `packages:write` |
233| `GET …/{package_name}/actions-access` | `list_package_actions_access` | `packages:read` |
234| `PUT …/{package_name}/actions-access` | `set_package_actions_access`: `repository` and `role` | `packages:write` |
235| `DELETE …/{package_name}/actions-access/{repository}` | `remove_package_actions_access` | `packages:write` |
236
237`version_id` is a version's id (`ver_…`), its version, its digest, or a tag
238that points to it. Reading access and deleted versions, and every change,
239also needs the Admin role on the package. Bodies and answers are
240snake_case.
241
242## Events and the audit log
243
244Publishing a version, deleting a version and deleting a package are
245[audit log](/guides/audit-log/) entries (so are deprecating an npm version,
246yanking or unyanking a crate version, unlisting or listing a NuGet version,
247pushing a NuGet version's symbols and yanking a gem version), as are
248restoring them, purging them after 30 days, every change to who has access
249and to Manage Actions access, changing the visibility, and linking and
250unlinking (see the [audit log's list](/guides/audit-log/)).
251
252[Webhooks](/guides/webhooks/) can subscribe to these events. A linked
253package's go to its repository's webhooks and its workspace's; an
254unlinked package's go to its workspace's webhooks.
255
256| Event | Sent when |
257| --- | --- |
258| `package.published` | A version is published. `data.tags` names the tags that now point to it. |
259| `package.version_deleted` | A version is deleted. |
260| `package.deleted` | A package is deleted. |
261| `package.visibility_changed` | A package is made public or private. `data.visibility` is the new one. |
262
263Each one's `data` has `package_id`, `workspace`, `ecosystem`, `name` and
264`repo_id` (null for an unlinked package); a version's event also has its
265`version` and `digest` (for a container image, the manifest's), and
266`package.published` its `size`, except for a Composer package.
267
268## Not supported yet
269
270- PyPI packages.
271- Installing unscoped npm packages, or other scopes, through g1t.sh, and
272 a copy of Packagist for Composer: those still come from their public
273 registries.
274- A Go module proxy: Go modules are fetched with git.
275- Workflows that run when a package is published.
276- Packages in site-wide search.