Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 1 | //! The packages service: the registries a workspace publishes to and |
| 2 | //! installs from, beside its code (docs/PACKAGES.md). Container images | |
| 3 | //! first, spoken over the OCI Distribution protocol on `g1t.sh/v2/`; npm, | |
| Merge branch 'worktree-agent-a6a121745e81f639f' | 4 | //! Composer, Cargo, Go, Maven, NuGet and RubyGems after. |
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 5 | //! |
| 6 | //! The site reaches it over `POST /rpc/<method>` with the arguments below; | |
| 7 | //! the registries' own protocols are any other request. Mirrors | |
| 8 | //! `packages/contracts/src/packages.ts`. | |
| 9 | //! | |
| 10 | //! Who may do what: a package linked to a repository has that | |
| Merge packages: roles, Actions access, source label, soft delete, API | 11 | //! repository's visibility and, unless its admins turned inheriting off, |
| 12 | //! its roles (Read pulls, Write publishes, Admin deletes and changes | |
| 13 | //! settings). An unlinked one belongs to its workspace: members by the base | |
| 14 | //! permission, owners administer. Either way the roles given on the package | |
| 15 | //! itself to people and teams ([`PackageAccess`]) add to those. A workflow | |
| 16 | //! job's token reaches a package only from the repository it is linked to, | |
| 17 | //! or from a repository given access under Manage Actions access | |
| 18 | //! ([`ActionsAccess`]). Public packages pull anonymously. | |
| 19 | //! | |
| 20 | //! Deleting a package or a version keeps it, hidden, for | |
| 21 | //! [`RESTORE_DAYS`]: an admin can restore it until then, and its name (or | |
| 22 | //! version) cannot be published again until it is purged. | |
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 23 | |
| 24 | use serde::{Deserialize, Serialize}; | |
| 25 | ||
| 26 | use crate::audit::Surface; | |
| 27 | use crate::{User, Viewer}; | |
| 28 | ||
| Merge packages: roles, Actions access, source label, soft delete, API | 29 | /// How long a deleted package or version can be restored, in days, before |
| 30 | /// the purge removes it for good. | |
| 31 | pub const RESTORE_DAYS: u64 = 30; | |
| 32 | ||
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 33 | /// Which registry a package is in. |
| 34 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] | |
| 35 | #[serde(rename_all = "snake_case")] | |
| 36 | pub enum Ecosystem { | |
| 37 | Container, | |
| 38 | Npm, | |
| 39 | Composer, | |
| 40 | Cargo, | |
| 41 | Go, | |
| Merge branch 'worktree-agent-a6a121745e81f639f' | 42 | Maven, |
| 43 | Nuget, | |
| 44 | Rubygems, | |
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 45 | } |
| 46 | ||
| 47 | impl Ecosystem { | |
| Merge branch 'worktree-agent-a6a121745e81f639f' | 48 | pub const ALL: [Ecosystem; 8] = [ |
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 49 | Ecosystem::Container, |
| 50 | Ecosystem::Npm, | |
| 51 | Ecosystem::Composer, | |
| 52 | Ecosystem::Cargo, | |
| 53 | Ecosystem::Go, | |
| Merge branch 'worktree-agent-a6a121745e81f639f' | 54 | Ecosystem::Maven, |
| 55 | Ecosystem::Nuget, | |
| 56 | Ecosystem::Rubygems, | |
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 57 | ]; |
| 58 | ||
| 59 | pub fn as_str(self) -> &'static str { | |
| 60 | match self { | |
| 61 | Ecosystem::Container => "container", | |
| 62 | Ecosystem::Npm => "npm", | |
| 63 | Ecosystem::Composer => "composer", | |
| 64 | Ecosystem::Cargo => "cargo", | |
| 65 | Ecosystem::Go => "go", | |
| Merge branch 'worktree-agent-a6a121745e81f639f' | 66 | Ecosystem::Maven => "maven", |
| 67 | Ecosystem::Nuget => "nuget", | |
| 68 | Ecosystem::Rubygems => "rubygems", | |
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 69 | } |
| 70 | } | |
| 71 | ||
| 72 | pub fn parse(text: &str) -> Option<Ecosystem> { | |
| 73 | Ecosystem::ALL.into_iter().find(|e| e.as_str() == text) | |
| 74 | } | |
| 75 | } | |
| 76 | ||
| 77 | #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] | |
| 78 | #[serde(rename_all = "snake_case")] | |
| 79 | pub enum Visibility { | |
| 80 | Public, | |
| 81 | #[default] | |
| 82 | Private, | |
| 83 | } | |
| 84 | ||
| 85 | impl Visibility { | |
| 86 | pub fn as_str(self) -> &'static str { | |
| 87 | match self { | |
| 88 | Visibility::Public => "public", | |
| 89 | Visibility::Private => "private", | |
| 90 | } | |
| 91 | } | |
| 92 | ||
| 93 | pub fn parse(text: &str) -> Visibility { | |
| 94 | if text == "public" { Visibility::Public } else { Visibility::Private } | |
| 95 | } | |
| 96 | } | |
| 97 | ||
| 98 | /// The repository a package is linked to. | |
| 99 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] | |
| 100 | pub struct LinkedRepo { | |
| 101 | pub id: String, | |
| 102 | pub namespace: String, | |
| 103 | pub name: String, | |
| 104 | } | |
| 105 | ||
| 106 | /// A package as listings show it. | |
| 107 | #[derive(Clone, Debug, Serialize, Deserialize)] | |
| 108 | pub struct PackageSummary { | |
| 109 | pub id: String, | |
| 110 | pub workspace: String, | |
| 111 | pub ecosystem: Ecosystem, | |
| 112 | /// Without the workspace: `web` for `g1t.sh/acme/web`. | |
| 113 | pub name: String, | |
| 114 | /// What a client is given: `g1t.sh/acme/web` for a container image. | |
| 115 | pub address: String, | |
| 116 | /// Linked packages follow their repository's visibility. | |
| 117 | pub visibility: Visibility, | |
| 118 | pub repo: Option<LinkedRepo>, | |
| 119 | pub description: Option<String>, | |
| 120 | pub versions: u32, | |
| 121 | /// The newest version's tag (for a container image, `latest` when it | |
| 122 | /// has one) or version. | |
| 123 | pub latest: Option<String>, | |
| 124 | /// Bytes its versions hold, each file counted once. | |
| 125 | pub size: u64, | |
| 126 | /// Pulls and installs, counted approximately. | |
| 127 | pub downloads: u64, | |
| 128 | pub created_at: String, | |
| 129 | pub updated_at: String, | |
| Merge packages: roles, Actions access, source label, soft delete, API | 130 | /// For a linked package: whether it takes its repository's roles. Its |
| 131 | /// own grants add to them either way. | |
| 132 | #[serde(default = "yes")] | |
| 133 | pub inherit_access: bool, | |
| 134 | /// Set on a deleted package: when, and by whom (a username). | |
| 135 | #[serde(default)] | |
| 136 | pub deleted_at: Option<String>, | |
| 137 | #[serde(default)] | |
| 138 | pub deleted_by: Option<String>, | |
| 139 | /// When a deleted package is purged: it can be restored until then. | |
| 140 | #[serde(default)] | |
| 141 | pub purge_at: Option<String>, | |
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 142 | } |
| 143 | ||
| Merge packages: roles, Actions access, source label, soft delete, API | 144 | fn yes() -> bool { |
| 145 | true | |
| 146 | } | |
| 147 | ||
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 148 | /// One version: for a container image, one manifest, by digest. |
| 149 | #[derive(Clone, Debug, Serialize, Deserialize)] | |
| 150 | pub struct PackageVersion { | |
| 151 | pub id: String, | |
| 152 | /// A tag, semver or (for container images) the manifest's digest. | |
| 153 | pub version: String, | |
| 154 | pub digest: String, | |
| 155 | /// Bytes of its files: an image's layers, config and manifest. | |
| 156 | pub size: u64, | |
| 157 | pub media_type: Option<String>, | |
| 158 | /// For an OCI artifact: what it is, such as a signature or an SBOM. | |
| 159 | pub artifact_type: Option<String>, | |
| 160 | /// For an artifact attached to another version: that version's digest. | |
| 161 | pub subject: Option<String>, | |
| 162 | /// For an image index: the platforms it holds, such as `linux/amd64`. | |
| 163 | pub platforms: Vec<String>, | |
| 164 | pub tags: Vec<String>, | |
| 165 | /// The username that published it. | |
| 166 | pub published_by: Option<String>, | |
| 167 | pub published_at: String, | |
| npm on g1t.sh: publish and install @<workspace>/<name> with the npm CLI and a g1t token | 168 | /// npm: why the version should no longer be used, when it is deprecated. |
| 169 | #[serde(default)] | |
| 170 | pub deprecated: Option<String>, | |
| Merge branch 'worktree-agent-ac1de8a731938ed81' | 171 | /// NuGet: whether a symbol package (`.snupkg`) was pushed for it. |
| 172 | #[serde(default)] | |
| 173 | pub symbols: bool, | |
| Merge packages: roles, Actions access, source label, soft delete, API | 174 | /// Its own pulls or downloads, counted approximately. |
| Merge branch 'worktree-agent-ac1de8a731938ed81' | 175 | #[serde(default)] |
| 176 | pub downloads: Option<u64>, | |
| Merge packages: roles, Actions access, source label, soft delete, API | 177 | /// Set on a deleted version: when, and by whom (a username). |
| 178 | #[serde(default)] | |
| 179 | pub deleted_at: Option<String>, | |
| 180 | #[serde(default)] | |
| 181 | pub deleted_by: Option<String>, | |
| 182 | /// When a deleted version is purged: it can be restored until then. | |
| 183 | #[serde(default)] | |
| 184 | pub purge_at: Option<String>, | |
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 185 | } |
| 186 | ||
| 187 | #[derive(Clone, Debug, Serialize, Deserialize)] | |
| 188 | pub struct PackageTag { | |
| 189 | pub tag: String, | |
| 190 | pub digest: String, | |
| 191 | pub updated_at: String, | |
| 192 | } | |
| 193 | ||
| 194 | /// What the viewer may do with a package. | |
| 195 | #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] | |
| 196 | pub struct PackagePermissions { | |
| 197 | pub pull: bool, | |
| 198 | pub push: bool, | |
| Merge packages: roles, Actions access, source label, soft delete, API | 199 | /// Delete and restore it and its versions. |
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 200 | pub delete: bool, |
| Merge packages: roles, Actions access, source label, soft delete, API | 201 | /// Change its settings: access, Actions access, visibility and link. |
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 202 | pub admin: bool, |
| 203 | } | |
| 204 | ||
| Merge packages: roles, Actions access, source label, soft delete, API | 205 | /// A role on a package. Read pulls, Write publishes, Admin deletes, |
| 206 | /// restores and changes its settings. | |
| 207 | #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] | |
| 208 | #[serde(rename_all = "snake_case")] | |
| 209 | pub enum PackageRole { | |
| 210 | Read, | |
| 211 | Write, | |
| 212 | Admin, | |
| 213 | } | |
| 214 | ||
| 215 | impl PackageRole { | |
| 216 | pub fn as_str(self) -> &'static str { | |
| 217 | match self { | |
| 218 | PackageRole::Read => "read", | |
| 219 | PackageRole::Write => "write", | |
| 220 | PackageRole::Admin => "admin", | |
| 221 | } | |
| 222 | } | |
| 223 | ||
| 224 | pub fn parse(text: &str) -> Option<PackageRole> { | |
| 225 | match text.trim().to_ascii_lowercase().as_str() { | |
| 226 | "read" | "pull" => Some(PackageRole::Read), | |
| 227 | "write" | "push" => Some(PackageRole::Write), | |
| 228 | "admin" => Some(PackageRole::Admin), | |
| 229 | _ => None, | |
| 230 | } | |
| 231 | } | |
| 232 | ||
| 233 | /// "Read", for sentences. | |
| 234 | pub fn label(self) -> &'static str { | |
| 235 | match self { | |
| 236 | PackageRole::Read => "Read", | |
| 237 | PackageRole::Write => "Write", | |
| 238 | PackageRole::Admin => "Admin", | |
| 239 | } | |
| 240 | } | |
| 241 | } | |
| 242 | ||
| 243 | /// Who a [`PackageAccess`] is for. | |
| 244 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] | |
| 245 | #[serde(rename_all = "snake_case")] | |
| 246 | pub enum GranteeKind { | |
| 247 | User, | |
| 248 | Team, | |
| 249 | } | |
| 250 | ||
| 251 | impl GranteeKind { | |
| 252 | pub fn as_str(self) -> &'static str { | |
| 253 | match self { | |
| 254 | GranteeKind::User => "user", | |
| 255 | GranteeKind::Team => "team", | |
| 256 | } | |
| 257 | } | |
| 258 | ||
| 259 | pub fn parse(text: &str) -> Option<GranteeKind> { | |
| 260 | match text { | |
| 261 | "user" => Some(GranteeKind::User), | |
| 262 | "team" => Some(GranteeKind::Team), | |
| 263 | _ => None, | |
| 264 | } | |
| 265 | } | |
| 266 | } | |
| 267 | ||
| 268 | /// A person or a team with a role on a package itself. | |
| 269 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] | |
| 270 | pub struct PackageAccess { | |
| 271 | pub kind: GranteeKind, | |
| 272 | /// The person's or the team's id. | |
| 273 | pub id: String, | |
| 274 | /// A username, or a team as `workspace/slug`. | |
| 275 | pub name: String, | |
| 276 | pub role: PackageRole, | |
| 277 | pub created_at: String, | |
| 278 | } | |
| 279 | ||
| 280 | /// A repository whose workflow jobs may use a package (Manage Actions | |
| 281 | /// access). The repository a package is linked to is listed with `linked` | |
| 282 | /// set: its jobs may always publish it. | |
| 283 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] | |
| 284 | pub struct ActionsAccess { | |
| 285 | pub repo_id: String, | |
| 286 | /// `owner/name`. | |
| 287 | pub repo: String, | |
| 288 | /// Read or Write. | |
| 289 | pub role: PackageRole, | |
| 290 | #[serde(default)] | |
| 291 | pub linked: bool, | |
| 292 | #[serde(default)] | |
| 293 | pub created_at: Option<String>, | |
| 294 | } | |
| 295 | ||
| 296 | /// `package_settings`: what a package's admins see on its Settings tab. | |
| 297 | #[derive(Clone, Debug, Serialize, Deserialize)] | |
| 298 | pub struct PackageSettings { | |
| 299 | pub package: PackageSummary, | |
| 300 | pub access: Vec<PackageAccess>, | |
| 301 | pub actions_access: Vec<ActionsAccess>, | |
| 302 | /// Its deleted versions that can still be restored, newest first. | |
| 303 | pub deleted_versions: Vec<PackageVersion>, | |
| 304 | pub permissions: PackagePermissions, | |
| 305 | } | |
| 306 | ||
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 307 | /// `get_package`. |
| 308 | #[derive(Clone, Debug, Serialize, Deserialize)] | |
| 309 | pub struct PackageDetail { | |
| 310 | pub package: PackageSummary, | |
| 311 | /// Newest first. | |
| 312 | pub versions: Vec<PackageVersion>, | |
| 313 | pub tags: Vec<PackageTag>, | |
| 314 | pub permissions: PackagePermissions, | |
| npm on g1t.sh: publish and install @<workspace>/<name> with the npm CLI and a g1t token | 315 | /// The package's README, as markdown: npm's, from its latest version. |
| 316 | #[serde(default)] | |
| 317 | pub readme: Option<String>, | |
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 318 | } |
| 319 | ||
| 320 | /// `list_packages`: the packages in a workspace the viewer may pull, newest | |
| 321 | /// first. Returns `Outcome<Vec<PackageSummary>>`. | |
| 322 | #[derive(Clone, Debug, Default, Serialize, Deserialize)] | |
| 323 | pub struct ListPackagesArgs { | |
| 324 | pub workspace: String, | |
| 325 | pub viewer: Viewer, | |
| 326 | #[serde(default)] | |
| 327 | pub ecosystem: Option<Ecosystem>, | |
| 328 | /// Only those linked to this repository. | |
| 329 | #[serde(default)] | |
| 330 | pub repo_id: Option<String>, | |
| 331 | /// Matched against names. | |
| 332 | #[serde(default)] | |
| 333 | pub query: Option<String>, | |
| 334 | } | |
| 335 | ||
| 336 | /// `get_package`. Returns `Outcome<PackageDetail>`; not found when the | |
| 337 | /// viewer may not pull it. | |
| 338 | #[derive(Clone, Debug, Serialize, Deserialize)] | |
| 339 | pub struct GetPackageArgs { | |
| 340 | pub workspace: String, | |
| 341 | pub ecosystem: Ecosystem, | |
| 342 | pub name: String, | |
| 343 | pub viewer: Viewer, | |
| 344 | } | |
| 345 | ||
| Merge packages: roles, Actions access, source label, soft delete, API | 346 | /// `delete_version`: a version, by its id, version or digest, or by a tag |
| 347 | /// that points to it. It is hidden at once and can be restored for | |
| 348 | /// [`RESTORE_DAYS`]; its tags come back with it unless they were moved | |
| 349 | /// meanwhile. Needs Admin. Returns `Outcome<()>`. | |
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 350 | #[derive(Clone, Debug, Serialize, Deserialize)] |
| 351 | pub struct DeleteVersionArgs { | |
| 352 | pub actor: User, | |
| 353 | pub workspace: String, | |
| 354 | pub ecosystem: Ecosystem, | |
| 355 | pub name: String, | |
| 356 | pub version: String, | |
| 357 | #[serde(default)] | |
| 358 | pub surface: Option<Surface>, | |
| 359 | } | |
| 360 | ||
| Merge packages: roles, Actions access, source label, soft delete, API | 361 | /// `delete_package`: a package and every version, hidden at once and |
| 362 | /// restorable for [`RESTORE_DAYS`]; its name stays taken until then. | |
| 363 | /// Needs Admin. Returns `Outcome<()>`. | |
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 364 | #[derive(Clone, Debug, Serialize, Deserialize)] |
| 365 | pub struct DeletePackageArgs { | |
| 366 | pub actor: User, | |
| 367 | pub workspace: String, | |
| 368 | pub ecosystem: Ecosystem, | |
| 369 | pub name: String, | |
| 370 | #[serde(default)] | |
| 371 | pub surface: Option<Surface>, | |
| 372 | } | |
| 373 | ||
| Merge packages: roles, Actions access, source label, soft delete, API | 374 | /// `set_package`: change a package's visibility, the repository it is |
| 375 | /// linked to, or whether it takes that repository's roles. `link` names a | |
| 376 | /// repository of its workspace (Admin on it is needed too); `unlink` takes | |
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 377 | /// the link away (the package is then the workspace's, and private until |
| 378 | /// someone makes it public). A linked package's visibility is its | |
| 379 | /// repository's, so `visibility` is refused for one. Needs Admin. Returns | |
| 380 | /// `Outcome<PackageSummary>`. | |
| 381 | #[derive(Clone, Debug, Serialize, Deserialize)] | |
| 382 | pub struct SetPackageArgs { | |
| 383 | pub actor: User, | |
| 384 | pub workspace: String, | |
| 385 | pub ecosystem: Ecosystem, | |
| 386 | pub name: String, | |
| 387 | #[serde(default)] | |
| 388 | pub visibility: Option<Visibility>, | |
| 389 | #[serde(default)] | |
| 390 | pub link: Option<String>, | |
| 391 | #[serde(default)] | |
| 392 | pub unlink: bool, | |
| Merge packages: roles, Actions access, source label, soft delete, API | 393 | /// For a linked package: whether it takes its repository's roles. |
| 394 | #[serde(default)] | |
| 395 | pub inherit_access: Option<bool>, | |
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 396 | #[serde(default)] |
| 397 | pub surface: Option<Surface>, | |
| 398 | } | |
| 399 | ||
| Merge packages: roles, Actions access, source label, soft delete, API | 400 | /// `package_settings`: a package's access, Actions access and deleted |
| 401 | /// versions. Admins only; not found for anyone who may not pull it. | |
| 402 | /// Returns `Outcome<PackageSettings>`. | |
| 403 | #[derive(Clone, Debug, Serialize, Deserialize)] | |
| 404 | pub struct PackageSettingsArgs { | |
| 405 | pub workspace: String, | |
| 406 | pub ecosystem: Ecosystem, | |
| 407 | pub name: String, | |
| 408 | pub viewer: Viewer, | |
| 409 | } | |
| 410 | ||
| 411 | /// `list_versions`: a package's versions, newest first: active ones, or | |
| 412 | /// with `deleted` the deleted ones that can still be restored (admins | |
| 413 | /// only). Returns `Outcome<Vec<PackageVersion>>`. | |
| 414 | #[derive(Clone, Debug, Serialize, Deserialize)] | |
| 415 | pub struct ListVersionsArgs { | |
| 416 | pub workspace: String, | |
| 417 | pub ecosystem: Ecosystem, | |
| 418 | pub name: String, | |
| 419 | pub viewer: Viewer, | |
| 420 | #[serde(default)] | |
| 421 | pub deleted: bool, | |
| 422 | } | |
| 423 | ||
| 424 | /// `get_version`: one version by its id, version, digest or a tag that | |
| 425 | /// points to it. Returns `Outcome<PackageVersion>`. | |
| 426 | #[derive(Clone, Debug, Serialize, Deserialize)] | |
| 427 | pub struct GetVersionArgs { | |
| 428 | pub workspace: String, | |
| 429 | pub ecosystem: Ecosystem, | |
| 430 | pub name: String, | |
| 431 | pub viewer: Viewer, | |
| 432 | pub version: String, | |
| 433 | } | |
| 434 | ||
| 435 | /// `restore_package`: a deleted package, with every version it had when it | |
| 436 | /// was deleted, while it can still be restored. Needs Admin, as it was. | |
| 437 | /// Returns `Outcome<PackageSummary>`. | |
| 438 | #[derive(Clone, Debug, Serialize, Deserialize)] | |
| 439 | pub struct RestorePackageArgs { | |
| 440 | pub actor: User, | |
| 441 | pub workspace: String, | |
| 442 | pub ecosystem: Ecosystem, | |
| 443 | pub name: String, | |
| 444 | #[serde(default)] | |
| 445 | pub surface: Option<Surface>, | |
| 446 | } | |
| 447 | ||
| 448 | /// `restore_version`: a deleted version, by its id or version, while it | |
| 449 | /// can still be restored. Needs Admin. Returns `Outcome<PackageVersion>`. | |
| 450 | #[derive(Clone, Debug, Serialize, Deserialize)] | |
| 451 | pub struct RestoreVersionArgs { | |
| 452 | pub actor: User, | |
| 453 | pub workspace: String, | |
| 454 | pub ecosystem: Ecosystem, | |
| 455 | pub name: String, | |
| 456 | pub version: String, | |
| 457 | #[serde(default)] | |
| 458 | pub surface: Option<Surface>, | |
| 459 | } | |
| 460 | ||
| 461 | /// `deleted_packages`: a workspace's deleted packages that can still be | |
| 462 | /// restored, newest deletion first, those the viewer administers. Returns | |
| 463 | /// `Outcome<Vec<PackageSummary>>`. | |
| 464 | #[derive(Clone, Debug, Default, Serialize, Deserialize)] | |
| 465 | pub struct DeletedPackagesArgs { | |
| 466 | pub workspace: String, | |
| 467 | pub viewer: Viewer, | |
| 468 | } | |
| 469 | ||
| 470 | /// `set_package_access`: give a person (`user`, a username) or a team | |
| 471 | /// (`team`, its slug or `workspace/slug`) a role on the package, or change | |
| 472 | /// theirs. Needs Admin. Returns `Outcome<Vec<PackageAccess>>`. | |
| 473 | #[derive(Clone, Debug, Serialize, Deserialize)] | |
| 474 | pub struct SetPackageAccessArgs { | |
| 475 | pub actor: User, | |
| 476 | pub workspace: String, | |
| 477 | pub ecosystem: Ecosystem, | |
| 478 | pub name: String, | |
| 479 | #[serde(default)] | |
| 480 | pub user: Option<String>, | |
| 481 | #[serde(default)] | |
| 482 | pub team: Option<String>, | |
| 483 | pub role: PackageRole, | |
| 484 | #[serde(default)] | |
| 485 | pub surface: Option<Surface>, | |
| 486 | } | |
| 487 | ||
| 488 | /// `remove_package_access`: take a person's or a team's role on the | |
| 489 | /// package away. Needs Admin. Returns `Outcome<Vec<PackageAccess>>`. | |
| 490 | #[derive(Clone, Debug, Serialize, Deserialize)] | |
| 491 | pub struct RemovePackageAccessArgs { | |
| 492 | pub actor: User, | |
| 493 | pub workspace: String, | |
| 494 | pub ecosystem: Ecosystem, | |
| 495 | pub name: String, | |
| 496 | #[serde(default)] | |
| 497 | pub user: Option<String>, | |
| 498 | #[serde(default)] | |
| 499 | pub team: Option<String>, | |
| 500 | #[serde(default)] | |
| 501 | pub surface: Option<Surface>, | |
| 502 | } | |
| 503 | ||
| 504 | /// `set_actions_access`: let a repository of the package's workspace | |
| 505 | /// (`repo`, its name or `owner/name`) use the package from its workflows, | |
| 506 | /// with the Read or Write role. Needs Admin. Returns | |
| 507 | /// `Outcome<Vec<ActionsAccess>>`. | |
| 508 | #[derive(Clone, Debug, Serialize, Deserialize)] | |
| 509 | pub struct SetActionsAccessArgs { | |
| 510 | pub actor: User, | |
| 511 | pub workspace: String, | |
| 512 | pub ecosystem: Ecosystem, | |
| 513 | pub name: String, | |
| 514 | pub repo: String, | |
| 515 | pub role: PackageRole, | |
| 516 | #[serde(default)] | |
| 517 | pub surface: Option<Surface>, | |
| 518 | } | |
| 519 | ||
| 520 | /// `remove_actions_access`: stop a repository's workflows using the | |
| 521 | /// package. The linked repository cannot be removed: unlink the package | |
| 522 | /// instead. Needs Admin. Returns `Outcome<Vec<ActionsAccess>>`. | |
| 523 | #[derive(Clone, Debug, Serialize, Deserialize)] | |
| 524 | pub struct RemoveActionsAccessArgs { | |
| 525 | pub actor: User, | |
| 526 | pub workspace: String, | |
| 527 | pub ecosystem: Ecosystem, | |
| 528 | pub name: String, | |
| 529 | pub repo: String, | |
| 530 | #[serde(default)] | |
| 531 | pub surface: Option<Surface>, | |
| 532 | } | |
| 533 | ||
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 534 | /// `storage`: what a workspace's packages hold, each file counted once, as |
| 535 | /// public when any public package uses it. For billing. Returns | |
| 536 | /// [`PackageStorage`]. | |
| 537 | #[derive(Clone, Debug, Serialize, Deserialize)] | |
| 538 | pub struct StorageArgs { | |
| 539 | pub workspace: String, | |
| 540 | } | |
| 541 | ||
| Composer from the workspace's own repositories, and go get from g1t.sh | 542 | /// `sync_composer`: read a repository's Composer package again now, as a |
| 543 | /// push would: made, updated or deleted from its branches, tags and | |
| 544 | /// `composer.json`. Returns `bool`: whether it is a package. | |
| 545 | #[derive(Clone, Debug, Serialize, Deserialize)] | |
| 546 | pub struct SyncComposerArgs { | |
| 547 | pub repo_id: String, | |
| 548 | } | |
| 549 | ||
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 550 | #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] |
| 551 | pub struct PackageStorage { | |
| 552 | pub public_bytes: u64, | |
| 553 | pub private_bytes: u64, | |
| 554 | } | |
| 555 | ||
| 556 | /// `storage_all`: [`PackageStorage`] for every workspace that has | |
| 557 | /// packages, from one query, for billing's daily measure. Takes `{}`; | |
| 558 | /// returns `Vec<WorkspacePackageStorage>`, by workspace. | |
| 559 | #[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] | |
| 560 | pub struct WorkspacePackageStorage { | |
| 561 | pub workspace: String, | |
| 562 | pub public_bytes: u64, | |
| 563 | pub private_bytes: u64, | |
| 564 | } | |
| 565 | ||
| Merge packages: roles, Actions access, source label, soft delete, API | 566 | /// Every RPC method of the service, as the site's mirror lists them. |
| 567 | pub const METHODS: [&str; 18] = [ | |
| 568 | "list_packages", | |
| 569 | "get_package", | |
| 570 | "list_versions", | |
| 571 | "get_version", | |
| 572 | "delete_version", | |
| 573 | "delete_package", | |
| 574 | "restore_version", | |
| 575 | "restore_package", | |
| 576 | "deleted_packages", | |
| 577 | "set_package", | |
| 578 | "package_settings", | |
| 579 | "set_package_access", | |
| 580 | "remove_package_access", | |
| 581 | "set_actions_access", | |
| 582 | "remove_actions_access", | |
| 583 | "storage", | |
| 584 | "storage_all", | |
| 585 | "sync_composer", | |
| 586 | ]; | |
| 587 | ||
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 588 | #[cfg(test)] |
| 589 | mod tests { | |
| 590 | use super::*; | |
| 591 | ||
| 592 | #[test] | |
| Merge packages: roles, Actions access, source label, soft delete, API | 593 | fn roles_read_back_and_order() { |
| 594 | for role in [PackageRole::Read, PackageRole::Write, PackageRole::Admin] { | |
| 595 | assert_eq!(PackageRole::parse(role.as_str()), Some(role)); | |
| 596 | assert_eq!(serde_json::to_value(role).unwrap(), role.as_str()); | |
| 597 | } | |
| 598 | assert!(PackageRole::Read < PackageRole::Write && PackageRole::Write < PackageRole::Admin); | |
| 599 | assert_eq!(PackageRole::parse("maintain"), None); | |
| 600 | } | |
| 601 | ||
| 602 | #[test] | |
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 603 | fn ecosystems_read_back() { |
| 604 | for ecosystem in Ecosystem::ALL { | |
| 605 | assert_eq!(Ecosystem::parse(ecosystem.as_str()), Some(ecosystem)); | |
| 606 | assert_eq!(serde_json::to_value(ecosystem).unwrap(), ecosystem.as_str()); | |
| 607 | } | |
| 608 | assert_eq!(Visibility::parse("public"), Visibility::Public); | |
| 609 | assert_eq!(Visibility::parse("anything"), Visibility::Private); | |
| 610 | } | |
| 611 | ||
| 612 | /// The site's copy, `packages/contracts/src/packages.ts`, names the | |
| 613 | /// same ecosystems and methods. | |
| 614 | #[test] | |
| 615 | fn the_typescript_mirror_names_the_same_ecosystems_and_methods() { | |
| 616 | let ts = include_str!("../../../packages/contracts/src/packages.ts"); | |
| 617 | for ecosystem in Ecosystem::ALL { | |
| 618 | assert!(ts.contains(&format!("\"{}\"", ecosystem.as_str())), "{}", ecosystem.as_str()); | |
| 619 | } | |
| Merge packages: roles, Actions access, source label, soft delete, API | 620 | for method in METHODS { |
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 621 | assert!(ts.contains(&format!("\"{method}\"")), "{method}"); |
| 622 | } | |
| 623 | } | |
| 624 | } |
This file's history is long; its oldest lines are credited to the oldest commit read.