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 @@
+
+
+
+
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