diff --git a/app/components/badge-github-actions.hbs b/app/components/badge-github-actions.hbs new file mode 100644 index 00000000000..c11aa4f25b0 --- /dev/null +++ b/app/components/badge-github-actions.hbs @@ -0,0 +1,4 @@ + + {{ this.text }} + + diff --git a/app/components/badge-github-actions.js b/app/components/badge-github-actions.js new file mode 100644 index 00000000000..01404e4909a --- /dev/null +++ b/app/components/badge-github-actions.js @@ -0,0 +1,61 @@ +import Component from '@ember/component'; +import { computed } from '@ember/object'; +import { alias } from '@ember/object/computed'; + +export default Component.extend({ + tagName: 'span', + repository: alias('badge.attributes.repository'), + imageUrl: computed('badge.attributes.{repository,workflow_enc,branch,event}', function() { + const url = new URL(`https://github.com/${this.repository}/workflows/${this.workflow_enc}/badge.svg`); + + if (this.branch !== '') { + url.searchParams.set('branch', this.branch); + } + + if (this.event !== '') { + url.searchParams.set('event', this.event); + } + + return url.href; + }), + url: computed('badge.attributes.{repository,workflow,branch,event}', function() { + const url = new URL(`https://github.com/${this.repository}/actions`); + + let query = ''; + if (this.workflow !== '') { + query += `workflow:"${this.workflow}"`; + } + + if (this.branch !== '') { + query += `branch:"${this.branch}"`; + } + + if (this.event !== '') { + query += `event:"${this.event}"`; + } + + if (query !== '') { + url.searchParams.set('query', query); + } + + return url.href; + }), + workflow: computed('badge.attributes.workflow', function() { + return this.get('badge.attributes.workflow'); + }), + workflow_enc: computed('badge.attributes.workflow', function() { + return this.get('badge.attributes.workflow') + .split('/') + .map(encodeURIComponent) + .join('/'); + }), + branch: computed('badge.attributes.branch', function() { + return this.get('badge.attributes.branch') || 'master'; + }), + event: computed('badge.attributes.event', function() { + return this.get('badge.attributes.event') || ''; + }), + text: computed('badge', function() { + return `GitHub Actions workflow status for the ${this.workflow} workflow on the ${this.branch} branch`; + }), +}); diff --git a/src/models/badge.rs b/src/models/badge.rs index 675a18b8665..e2a84eb948e 100644 --- a/src/models/badge.rs +++ b/src/models/badge.rs @@ -39,6 +39,13 @@ pub enum Badge { pipeline: String, build: Option, }, + #[serde(rename = "github-actions")] + GitHubActions { + repository: String, + workflow: String, + branch: Option, + event: Option, + }, #[serde(rename = "gitlab")] GitLab { repository: String, diff --git a/src/tests/badge.rs b/src/tests/badge.rs index db3ccce24d6..70858db4810 100644 --- a/src/tests/badge.rs +++ b/src/tests/badge.rs @@ -7,6 +7,8 @@ struct BadgeRef { appveyor_attributes: HashMap, travis_ci: Badge, travis_ci_attributes: HashMap, + github_actions: Badge, + github_actions_attributes: HashMap, gitlab: Badge, gitlab_attributes: HashMap, azure_devops: Badge, @@ -78,6 +80,19 @@ fn set_up() -> (BadgeTestCrate, BadgeRef) { badge_attributes_travis_ci.insert(String::from("branch"), String::from("beta")); badge_attributes_travis_ci.insert(String::from("repository"), String::from("rust-lang/rust")); + let github_actions = Badge::GitHubActions { + repository: String::from("rust-lang/rust"), + workflow: String::from("build"), + branch: Some(String::from("beta")), + event: Some(String::from("push")), + }; + let mut badge_attributes_github_actions = HashMap::new(); + badge_attributes_github_actions + .insert(String::from("repository"), String::from("rust-lang/rust")); + badge_attributes_github_actions.insert(String::from("workflow"), String::from("build")); + badge_attributes_github_actions.insert(String::from("branch"), String::from("beta")); + badge_attributes_github_actions.insert(String::from("event"), String::from("push")); + let gitlab = Badge::GitLab { branch: Some(String::from("beta")), repository: String::from("rust-lang/rust"), @@ -169,6 +184,8 @@ fn set_up() -> (BadgeTestCrate, BadgeRef) { appveyor_attributes: badge_attributes_appveyor, travis_ci, travis_ci_attributes: badge_attributes_travis_ci, + github_actions, + github_actions_attributes: badge_attributes_github_actions, gitlab, gitlab_attributes: badge_attributes_gitlab, azure_devops, @@ -226,6 +243,20 @@ fn update_add_travis_ci() { assert_eq!(krate.badges(), vec![test_badges.travis_ci]); } +#[test] +fn update_add_github_actions() { + // Add a github actions badge + let (krate, test_badges) = set_up(); + + let mut badges = HashMap::new(); + badges.insert( + String::from("github-actions"), + test_badges.github_actions_attributes, + ); + krate.update(&badges); + assert_eq!(krate.badges(), vec![test_badges.github_actions]); +} + #[test] fn update_add_gitlab() { // Add a gitlab badge @@ -459,6 +490,46 @@ fn travis_ci_required_keys() { assert_eq!(krate.badges(), vec![]); } +#[test] +fn github_actions_required_key_repository() { + // Add a GitHub Actions badge missing the required repository field + let (krate, mut test_badges) = set_up(); + + let mut badges = HashMap::new(); + + // Repository is a required key + test_badges.github_actions_attributes.remove("repository"); + badges.insert( + String::from("github-actions"), + test_badges.github_actions_attributes, + ); + + let invalid_badges = krate.update(&badges); + assert_eq!(invalid_badges.len(), 1); + assert_eq!(invalid_badges.first().unwrap(), "github-actions"); + assert_eq!(krate.badges(), vec![]); +} + +#[test] +fn github_actions_required_key_workflow() { + // Add a GitHub Actions badge missing the required workflow field + let (krate, mut test_badges) = set_up(); + + let mut badges = HashMap::new(); + + // Workflow is a required key + test_badges.github_actions_attributes.remove("workflow"); + badges.insert( + String::from("github-actions"), + test_badges.github_actions_attributes, + ); + + let invalid_badges = krate.update(&badges); + assert_eq!(invalid_badges.len(), 1); + assert_eq!(invalid_badges.first().unwrap(), "github-actions"); + assert_eq!(krate.badges(), vec![]); +} + #[test] fn gitlab_required_keys() { // Add a gitlab badge missing a required field