Implement support for inline commands definition for projects
I think this will help the task definitions that don't line up to a development project
This commit is contained in:
parent
f8976aab10
commit
0d00fb4cfd
@ -3,9 +3,8 @@ projects:
|
||||
'inline-config':
|
||||
description: |
|
||||
An inline configured project
|
||||
filename: 'ci.synchronik.yml'
|
||||
scm:
|
||||
github:
|
||||
owner: 'rtyler'
|
||||
repo: 'synchronik'
|
||||
ref: 'main'
|
||||
inline:
|
||||
needs:
|
||||
- git
|
||||
commands:
|
||||
- 'whoami'
|
||||
|
@ -10,7 +10,7 @@ use crate::AppState;
|
||||
/*
|
||||
* Representation of the Synchronik YAML format
|
||||
*/
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct Yml {
|
||||
pub needs: Vec<String>,
|
||||
pub commands: Vec<String>,
|
||||
@ -19,6 +19,11 @@ pub struct Yml {
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum Scm {
|
||||
/*
|
||||
* The Nonexistent Scm is used for stubbing out the Scm properties when
|
||||
* inlining configuration
|
||||
*/
|
||||
Nonexistent,
|
||||
GitHub {
|
||||
owner: String,
|
||||
repo: String,
|
||||
@ -31,11 +36,22 @@ pub enum Scm {
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub struct Project {
|
||||
description: String,
|
||||
pub filename: String,
|
||||
#[serde(with = "serde_yaml::with::singleton_map")]
|
||||
/*
|
||||
* Used for optionally defining an inline Yml configuration
|
||||
*/
|
||||
inline: Option<Yml>,
|
||||
pub filename: Option<String>,
|
||||
#[serde(default = "default_scm", with = "serde_yaml::with::singleton_map")]
|
||||
pub scm: Scm,
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple default scm for use when nothing has been otherwise defined
|
||||
*/
|
||||
fn default_scm() -> Scm {
|
||||
Scm::Nonexistent
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal representation of an Agent that has been "loaded" by the server
|
||||
*
|
||||
@ -86,7 +102,7 @@ pub struct AgentConfig {
|
||||
pub url: Url,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||
pub struct ServerConfig {
|
||||
pub agents: HashMap<String, AgentConfig>,
|
||||
pub projects: HashMap<String, Project>,
|
||||
@ -157,21 +173,6 @@ impl ServerConfig {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Default trait implementation for ServerConfig, will result in an empty set of agents and
|
||||
* projects
|
||||
*
|
||||
* Not really useful for anything other than tests
|
||||
*/
|
||||
impl Default for ServerConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
agents: HashMap::default(),
|
||||
projects: HashMap::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Merge two Valus from <https://stackoverflow.com/a/67743348>
|
||||
*/
|
||||
@ -252,4 +253,58 @@ mod tests {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_config_with_scm() {
|
||||
let conf = r#"
|
||||
---
|
||||
agents:
|
||||
'Local':
|
||||
url: 'http://localhost:9000'
|
||||
projects:
|
||||
'synchronik':
|
||||
description: |
|
||||
Self-hosted project
|
||||
filename: 'ci.synchronik.yml'
|
||||
scm:
|
||||
github:
|
||||
owner: 'rtyler'
|
||||
repo: 'synchronik'
|
||||
ref: 'main'
|
||||
"#;
|
||||
let value: ServerConfig = serde_yaml::from_str(&conf).expect("Failed to parse");
|
||||
assert_eq!(value.agents.len(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_config_inline() {
|
||||
let conf = r#"
|
||||
---
|
||||
agents:
|
||||
'Local':
|
||||
url: 'http://localhost:9000'
|
||||
projects:
|
||||
'synchronik':
|
||||
description: |
|
||||
Self-hosted project
|
||||
inline:
|
||||
needs:
|
||||
- git
|
||||
commands:
|
||||
- 'whoami'
|
||||
"#;
|
||||
let value: ServerConfig = serde_yaml::from_str(&conf).expect("Failed to parse");
|
||||
assert_eq!(value.agents.len(), 1);
|
||||
assert_eq!(value.projects.len(), 1);
|
||||
|
||||
let project = value.projects.get("synchronik").unwrap();
|
||||
match &project.inline {
|
||||
Some(yml) => {
|
||||
assert!(yml.commands.contains(&"whoami".to_string()));
|
||||
}
|
||||
None => {
|
||||
assert!(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use sqlx::SqlitePool;
|
||||
|
||||
use crate::models::*;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct Run {
|
||||
run: RunRow,
|
||||
project: Project,
|
||||
@ -91,17 +91,6 @@ impl Run {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Run {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
run: RunRow::default(),
|
||||
project: Project::default(),
|
||||
scm_info: ScmInfo::default(),
|
||||
definition: RunDefinition::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -74,21 +74,20 @@ pub mod api {
|
||||
|
||||
if let Some(project) = state.config.projects.get(&name) {
|
||||
match &project.scm {
|
||||
Scm::Nonexistent => {}
|
||||
Scm::GitHub {
|
||||
owner,
|
||||
repo,
|
||||
scm_ref,
|
||||
} => {
|
||||
debug!(
|
||||
"Fetching the file {} from {}/{}",
|
||||
&project.filename, owner, repo
|
||||
);
|
||||
let filename = match &project.filename {
|
||||
None => "synchronik.yml".to_string(),
|
||||
Some(filename) => filename.to_string(),
|
||||
};
|
||||
debug!("Fetching the file {} from {}/{}", filename, owner, repo);
|
||||
let res = octocrab::instance()
|
||||
.repos(owner, repo)
|
||||
.raw_file(
|
||||
octocrab::params::repos::Commitish(scm_ref.into()),
|
||||
&project.filename,
|
||||
)
|
||||
.raw_file(octocrab::params::repos::Commitish(scm_ref.into()), filename)
|
||||
.await?;
|
||||
let config_file: Yml = serde_yaml::from_str(&res.text().await?)?;
|
||||
debug!("text: {:?}", config_file);
|
||||
|
Loading…
Reference in New Issue
Block a user