github_actions_models/dependabot/
v2.rs

1//! "v2" Dependabot models.
2//!
3//! Resources:
4//! * [Configuration options for the `dependabot.yml` file](https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file)
5//! * [JSON Schema for Dependabot v2](https://json.schemastore.org/dependabot-2.0.json)
6
7use indexmap::{IndexMap, IndexSet};
8use serde::Deserialize;
9
10/// A `dependabot.yml` configuration file.
11#[derive(Deserialize, Debug)]
12#[serde(rename_all = "kebab-case")]
13pub struct Dependabot {
14    /// Invariant: `2`
15    pub version: u64,
16    #[serde(default)]
17    pub enable_beta_ecosystems: bool,
18    #[serde(default)]
19    pub registries: IndexMap<String, Registry>,
20    pub updates: Vec<Update>,
21}
22
23/// Different registries known to Dependabot.
24#[derive(Deserialize, Debug)]
25#[serde(rename_all = "kebab-case", tag = "type")]
26pub enum Registry {
27    ComposerRepository {
28        url: String,
29        username: Option<String>,
30        password: Option<String>,
31    },
32    DockerRegistry {
33        url: String,
34        username: Option<String>,
35        password: Option<String>,
36        #[serde(default)]
37        replaces_base: bool,
38    },
39    Git {
40        url: String,
41        username: Option<String>,
42        password: Option<String>,
43    },
44    HexOrganization {
45        organization: String,
46        key: Option<String>,
47    },
48    HexRepository {
49        repo: Option<String>,
50        url: String,
51        auth_key: Option<String>,
52        public_key_fingerprint: Option<String>,
53    },
54    MavenRepository {
55        url: String,
56        username: Option<String>,
57        password: Option<String>,
58    },
59    NpmRegistry {
60        url: String,
61        username: Option<String>,
62        password: Option<String>,
63        #[serde(default)]
64        replaces_base: bool,
65    },
66    NugetFeed {
67        url: String,
68        username: Option<String>,
69        password: Option<String>,
70    },
71    PythonIndex {
72        url: String,
73        username: Option<String>,
74        password: Option<String>,
75        #[serde(default)]
76        replaces_base: bool,
77    },
78    RubygemsServer {
79        url: String,
80        username: Option<String>,
81        password: Option<String>,
82        #[serde(default)]
83        replaces_base: bool,
84    },
85    TerraformRegistry {
86        url: String,
87        token: Option<String>,
88    },
89}
90
91/// A single `update` directive.
92#[derive(Deserialize, Debug)]
93#[serde(rename_all = "kebab-case")]
94pub struct Update {
95    #[serde(default)]
96    pub allow: Vec<Allow>,
97    #[serde(default)]
98    pub assignees: IndexSet<String>,
99    pub commit_message: Option<CommitMessage>,
100    pub directory: String,
101    #[serde(default)]
102    pub groups: IndexMap<String, Group>,
103    #[serde(default)]
104    pub ignore: Vec<Ignore>,
105    #[serde(default)]
106    pub insecure_external_code_execution: AllowDeny,
107    /// Labels to apply to this update group's pull requests.
108    ///
109    /// The default label is `dependencies`.
110    #[serde(default = "default_labels")]
111    pub labels: IndexSet<String>,
112    pub milestone: Option<u64>,
113    /// The maximum number of pull requests to open at a time from this
114    /// update group.
115    ///
116    /// The default maximum is 5.
117    #[serde(default = "default_open_pull_requests_limit")]
118    pub open_pull_requests_limit: u64,
119    pub package_ecosystem: PackageEcosystem,
120    // TODO: pull-request-branch-name
121    #[serde(default)]
122    pub rebase_strategy: RebaseStrategy,
123    #[serde(default, deserialize_with = "crate::common::scalar_or_vector")]
124    pub registries: Vec<String>,
125    #[serde(default)]
126    pub reviewers: IndexSet<String>,
127    pub schedule: Schedule,
128    pub target_branch: Option<String>,
129    #[serde(default)]
130    pub vendor: bool,
131    pub versioning_strategy: Option<VersioningStrategy>,
132}
133
134#[inline]
135fn default_labels() -> IndexSet<String> {
136    IndexSet::from(["dependencies".to_string()])
137}
138
139#[inline]
140fn default_open_pull_requests_limit() -> u64 {
141    // https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#open-pull-requests-limit
142    5
143}
144
145/// Allow rules for Dependabot updates.
146#[derive(Deserialize, Debug)]
147#[serde(rename_all = "kebab-case")]
148pub struct Allow {
149    pub dependency_name: Option<String>,
150    pub dependency_type: Option<DependencyType>,
151}
152
153/// Dependency types in `allow` rules.
154#[derive(Deserialize, Debug)]
155#[serde(rename_all = "kebab-case")]
156pub enum DependencyType {
157    Direct,
158    Indirect,
159    All,
160    Production,
161    Development,
162}
163
164/// Commit message settings for Dependabot updates.
165#[derive(Deserialize, Debug)]
166#[serde(rename_all = "kebab-case")]
167pub struct CommitMessage {
168    pub prefix: Option<String>,
169    pub prefix_development: Option<String>,
170    /// Invariant: `"scope"`
171    pub include: Option<String>,
172}
173
174/// Group settings for batched updates.
175#[derive(Deserialize, Debug)]
176#[serde(rename_all = "kebab-case")]
177pub struct Group {
178    /// This can only be [`DependencyType::Development`] or
179    /// [`DependencyType::Production`].
180    pub dependency_type: Option<DependencyType>,
181    #[serde(default)]
182    pub patterns: IndexSet<String>,
183    #[serde(default)]
184    pub exclude_patterns: IndexSet<String>,
185    #[serde(default)]
186    pub update_types: IndexSet<UpdateType>,
187}
188
189/// Update types for grouping.
190#[derive(Deserialize, Debug, Hash, Eq, PartialEq)]
191#[serde(rename_all = "kebab-case")]
192pub enum UpdateType {
193    Major,
194    Minor,
195    Patch,
196}
197
198/// Dependency ignore settings for updates.
199#[derive(Deserialize, Debug)]
200#[serde(rename_all = "kebab-case")]
201pub struct Ignore {
202    pub dependency_name: Option<String>,
203    /// These are, inexplicably, not [`UpdateType`] variants.
204    /// Instead, they're strings like `"version-update:semver-{major,minor,patch}"`.
205    #[serde(default)]
206    pub update_types: IndexSet<String>,
207    #[serde(default)]
208    pub versions: IndexSet<String>,
209}
210
211/// An "allow"/"deny" toggle.
212#[derive(Deserialize, Debug, Default)]
213#[serde(rename_all = "kebab-case")]
214pub enum AllowDeny {
215    Allow,
216    #[default]
217    Deny,
218}
219
220/// Supported packaging ecosystems.
221#[derive(Deserialize, Debug, PartialEq)]
222#[serde(rename_all = "kebab-case")]
223pub enum PackageEcosystem {
224    Bundler,
225    Cargo,
226    Composer,
227    Docker,
228    Elm,
229    Gitsubmodule,
230    GithubActions,
231    Gomod,
232    Gradle,
233    Maven,
234    Mix,
235    Npm,
236    Nuget,
237    Pip,
238    Pub,
239    Swift,
240    Terraform,
241}
242
243/// Rebase strategies for Dependabot updates.
244#[derive(Deserialize, Debug, Default, PartialEq)]
245#[serde(rename_all = "kebab-case")]
246pub enum RebaseStrategy {
247    #[default]
248    Auto,
249    Disabled,
250}
251
252/// Scheduling settings for Dependabot updates.
253#[derive(Deserialize, Debug)]
254#[serde(rename_all = "kebab-case")]
255pub struct Schedule {
256    pub interval: Interval,
257    pub day: Option<Day>,
258    pub time: Option<String>,
259    pub timezone: Option<String>,
260}
261
262/// Schedule intervals.
263#[derive(Deserialize, Debug, PartialEq)]
264#[serde(rename_all = "kebab-case")]
265pub enum Interval {
266    Daily,
267    Weekly,
268    Monthly,
269}
270
271/// Days of the week.
272#[derive(Deserialize, Debug, PartialEq)]
273#[serde(rename_all = "kebab-case")]
274pub enum Day {
275    Monday,
276    Tuesday,
277    Wednesday,
278    Thursday,
279    Friday,
280    Saturday,
281    Sunday,
282}
283
284/// Versioning strategies.
285#[derive(Deserialize, Debug, PartialEq)]
286#[serde(rename_all = "kebab-case")]
287pub enum VersioningStrategy {
288    Auto,
289    Increase,
290    IncreaseIfNecessary,
291    LockfileOnly,
292    Widen,
293}