1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use super::super::{
Amd64Variant, PostPublishPollConfig, StringOrBool, deserialize_string_or_bool_opt,
};
use super::RepositoryConfig;
// ---------------------------------------------------------------------------
// ChocolateyConfig
// ---------------------------------------------------------------------------
#[derive(Debug, Clone, Serialize, Deserialize, Default, JsonSchema)]
#[serde(default, deny_unknown_fields)]
pub struct ChocolateyConfig {
/// Override the package name (default: crate name).
pub name: Option<String>,
/// Build IDs filter: only include artifacts whose `id` is in this list.
pub ids: Option<Vec<String>>,
/// Unified project repo config (owner/name). Used to derive
/// `<projectUrl>` (the Chocolatey gallery link) and download URLs.
/// `<projectUrl>` resolves through `project_url:` (if set) → derived
/// `https://github.com/{repository.owner}/{repository.name}`.
pub repository: Option<RepositoryConfig>,
/// URL shown as the package source in the Chocolatey gallery.
pub package_source_url: Option<String>,
/// Package owners (Chocolatey gallery user).
pub owners: Option<String>,
/// Package title (default: project name).
pub title: Option<String>,
/// Package author(s) displayed in the Chocolatey gallery.
pub authors: Option<String>,
/// Project homepage URL.
pub project_url: Option<String>,
/// Custom URL template for download URLs (overrides release URL).
pub url_template: Option<String>,
/// URL to the package icon image shown in the Chocolatey gallery.
pub icon_url: Option<String>,
/// Copyright notice.
pub copyright: Option<String>,
/// Package description (supports markdown).
pub description: Option<String>,
/// SPDX license expression (e.g. "MIT", "Apache-2.0", "MIT OR Apache-2.0").
/// Not emitted as a nuspec element — Chocolatey CLI does not support the
/// NuGet `<license>` element (it warns CHCU0002: "use <licenseUrl>
/// instead") — it gates the `<licenseUrl>` derivation: a single
/// identifier derives a LICENSE blob URL; a compound expression has no
/// single canonical file, so set `license_url` explicitly.
pub license: Option<String>,
/// Optional explicit `<licenseUrl>` — Chocolatey's only supported license
/// metadata. When unset, anodizer derives a real GitHub
/// `…/blob/<tag>/LICENSE` URL from `repository` (what ripgrep / fd /
/// gh ship); when no repository is known or `license` is a compound SPDX
/// expression, no `<licenseUrl>` is emitted.
/// anodizer never synthesizes an `opensource.org/licenses/<spdx>` URL —
/// it 404s for compound SPDX and gets the package rejected at moderation.
pub license_url: Option<String>,
/// Require license acceptance before install.
pub require_license_acceptance: Option<bool>,
/// Source code project URL (`<projectSourceUrl>`). Defaults to the derived
/// `repository` URL when unset.
pub project_source_url: Option<String>,
/// Documentation URL.
pub docs_url: Option<String>,
/// Bug tracker URL (`<bugTrackerUrl>`). Defaults to `{repository}/issues`
/// when unset.
pub bug_tracker_url: Option<String>,
/// Tags for the Chocolatey gallery (joined with single spaces in the
/// emitted nuspec). Always a typed list — the legacy
/// space-separated-string form was dropped now for
/// IDE-completion friendliness and to remove whitespace ambiguity.
pub tags: Option<Vec<String>>,
/// Short summary of the package.
pub summary: Option<String>,
/// Release notes for this version.
pub release_notes: Option<String>,
/// Package dependencies with optional version constraints.
pub dependencies: Option<Vec<ChocolateyDependency>>,
/// Chocolatey API key for `choco push`. Falls back to `CHOCOLATEY_API_KEY` env var.
pub api_key: Option<String>,
/// Push source URL (default: "https://push.chocolatey.org/").
pub source_repo: Option<String>,
/// Skip pushing to the Chocolatey community repository. Bool, string, or
/// template expression (e.g. `"{{ IsSnapshot }}"`). Accepts the legacy
/// `skip_publish:` spelling for back-compat with configs;
/// canonical name is `skip:` to align with every other publisher.
#[serde(
default,
alias = "skip_publish",
deserialize_with = "deserialize_string_or_bool_opt"
)]
pub skip: Option<StringOrBool>,
/// Artifact selection: "archive" (default), "msi", or "nsis".
#[serde(rename = "use")]
pub use_artifact: Option<String>,
/// amd64 microarchitecture variant filter (`v1` / `v2` / `v3` / `v4`).
/// Only artifacts matching this variant are included. Default: `v1`.
/// Typed as [`Amd64Variant`], so any value outside `v1`..`v4` is
/// rejected when the config is parsed.
pub amd64_variant: Option<Amd64Variant>,
/// Post-publish moderation-queue polling settings. Polling is
/// disabled by default — Chocolatey's community moderation queue
/// routinely takes hours to days, and blocking a CI workflow on
/// that wait is wrong. Opt in per-publisher with
/// `post_publish_poll: { enabled: true }` when running locally and
/// willing to wait, or disable globally via `--no-post-publish-poll`.
pub post_publish_poll: Option<PostPublishPollConfig>,
/// When true, re-push the nupkg even when a version is already in the
/// community moderation queue (PackageStatus=Submitted). Chocolatey's API
/// accepts re-pushes of in-moderation versions; the new nupkg replaces the
/// queued one. When false (default), the push is skipped and a warning is
/// emitted so the operator sees that the publisher did not push.
#[serde(deserialize_with = "deserialize_string_or_bool_opt", default)]
pub republish_in_moderation: Option<StringOrBool>,
/// Override whether this publisher failing should fail the overall release.
///
/// Default: `false` — a failure here is logged but does not abort the release.
/// Set to `true` to fail the release on any error.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub required: Option<bool>,
/// Template-conditional gate: when the rendered result is falsy
/// (`"false"` / `"0"` / `"no"` / empty), the Chocolatey publisher is
/// skipped. Render failure hard-errors. Config key: `chocolateys[].if:`.
#[serde(rename = "if")]
pub if_condition: Option<String>,
/// When `true`, a triggered rollback leaves this publisher's work in
/// place rather than attempting to undo it. Default `false`.
pub retain_on_rollback: Option<bool>,
}
/// Chocolatey package dependency with optional version constraint.
#[derive(Debug, Clone, Serialize, Deserialize, Default, JsonSchema)]
#[serde(default, deny_unknown_fields)]
pub struct ChocolateyDependency {
/// Chocolatey package ID of the dependency.
pub id: String,
/// Minimum version constraint for the dependency (e.g., "[1.0.0,)").
pub version: Option<String>,
}