diff options
author | Javier García Orduña <javier.garcia@sonarsource.com> | 2024-12-10 08:10:53 +0100 |
---|---|---|
committer | Steve Marion <steve.marion@sonarsource.com> | 2024-12-18 11:13:05 +0100 |
commit | 378471f2ece7bec0809dea18c7c84d9b85e4be83 (patch) | |
tree | 00a96ad9ad8f4f6d1deadff797212467f6549614 /sonar-scanner-engine | |
parent | 472ce41d22240984abeb126b9bcabfa6df61dea3 (diff) | |
download | sonarqube-378471f2ece7bec0809dea18c7c84d9b85e4be83.tar.gz sonarqube-378471f2ece7bec0809dea18c7c84d9b85e4be83.zip |
SONAR-22640 Read PR head sha from trigger event of GitHub action
Diffstat (limited to 'sonar-scanner-engine')
3 files changed, 634 insertions, 32 deletions
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/GithubActions.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/GithubActions.java index 5cc999b72e1..8955621dcbe 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/GithubActions.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/GithubActions.java @@ -19,6 +19,12 @@ */ package org.sonar.scanner.ci.vendors; +import com.google.gson.Gson; +import com.google.gson.annotations.SerializedName; +import java.io.File; +import java.io.IOException; +import java.util.Optional; +import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,6 +34,8 @@ import org.sonar.scanner.ci.CiConfigurationImpl; import org.sonar.scanner.ci.CiVendor; import org.sonar.scanner.ci.DevOpsPlatformInfo; +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.apache.commons.lang.StringUtils.isNotBlank; import static org.apache.commons.lang3.StringUtils.isEmpty; /** @@ -39,9 +47,13 @@ public class GithubActions implements CiVendor { private static final Logger LOG = LoggerFactory.getLogger(GithubActions.class); - private static final String PROPERTY_COMMIT = "GITHUB_SHA"; + public static final String GITHUB_SHA = "GITHUB_SHA"; public static final String GITHUB_REPOSITORY_ENV_VAR = "GITHUB_REPOSITORY"; public static final String GITHUB_API_URL_ENV_VAR = "GITHUB_API_URL"; + public static final String GITHUB_EVENT_PATH = "GITHUB_EVENT_PATH"; + public static final String GITHUB_EVENT_NAME = "GITHUB_EVENT_NAME"; + public static final String GITHUB_ACTION = "GITHUB_ACTION"; + public static final String NAME = "Github Actions"; private final System2 system; @@ -51,28 +63,134 @@ public class GithubActions implements CiVendor { @Override public String getName() { - return "Github Actions"; + return NAME; } @Override public boolean isDetected() { - return StringUtils.isNotBlank(system.envVariable("GITHUB_ACTION")); + return StringUtils.isNotBlank(system.envVariable(GITHUB_ACTION)); } @Override public CiConfiguration loadConfiguration() { - String revision = system.envVariable(PROPERTY_COMMIT); - if (isEmpty(revision)) { - LOG.warn("Missing environment variable " + PROPERTY_COMMIT); - } + String revision = getScmRevision().orElse(null); + return getDevOpsPlatformInfo().map(devOpsPlatformInfo -> new CiConfigurationImpl(revision, getName(), devOpsPlatformInfo)) + .orElseGet(() -> new CiConfigurationImpl(revision, getName())); + } + private Optional<DevOpsPlatformInfo> getDevOpsPlatformInfo() { String githubRepository = system.envVariable(GITHUB_REPOSITORY_ENV_VAR); String githubApiUrl = system.envVariable(GITHUB_API_URL_ENV_VAR); if (isEmpty(githubRepository) || isEmpty(githubApiUrl)) { LOG.warn("Missing or empty environment variables: {}, and/or {}", GITHUB_API_URL_ENV_VAR, GITHUB_REPOSITORY_ENV_VAR); - return new CiConfigurationImpl(revision, getName()); + return Optional.empty(); + } + return Optional.of(new DevOpsPlatformInfo(githubApiUrl, githubRepository)); + } + + private Optional<String> getScmRevision() { + Optional<String> revisionOpt = getScmRevisionIfPullRequest(); + if (revisionOpt.isPresent()) { + return revisionOpt; + } + return getScmRevisionFromEnvVar(); + } + + private Optional<String> getScmRevisionIfPullRequest() { + String path = system.envVariable(GITHUB_EVENT_PATH); + String eventName = system.envVariable(GITHUB_EVENT_NAME); + boolean detected = isNotBlank(eventName) && isNotBlank(path); + if (!detected) { + return Optional.empty(); + } + + if ("pull_request".equals(eventName)) { + String json = readFile(path); + PrEvent prEvent = new Gson().fromJson(json, PrEvent.class); + return Optional.of(prEvent.pullRequest.head.sha); + } + return Optional.empty(); + } + + private Optional<String> getScmRevisionFromEnvVar() { + String revision = system.envVariable(GITHUB_SHA); + if (isEmpty(revision)) { + LOG.warn("Missing environment variable " + GITHUB_SHA); + return Optional.empty(); + } + return Optional.of(revision); + } + + private static String readFile(String path) { + File file = new File(path); + if (!file.exists() || !file.isFile()) { + throw new IllegalStateException("Event file does not exist: " + file); } - return new CiConfigurationImpl(revision, getName(), new DevOpsPlatformInfo(githubApiUrl, githubRepository)); + try { + return FileUtils.readFileToString(file, UTF_8); + } catch (IOException e) { + throw new IllegalStateException("Fail to read event file: " + file, e); + } + } + + @SuppressWarnings("ALL") + private static class PrEvent { + @SerializedName("ref") + private String ref; + + @SerializedName("pull_request") + private Pr pullRequest; + } + + @SuppressWarnings("ALL") + private static class Pr { + @SerializedName("number") + private int number; + + @SerializedName("base") + private PrCommit base; + + @SerializedName("head") + private PrCommit head; + } + + @SuppressWarnings("ALL") + private static class PrCommit { + @SerializedName("ref") + private String ref; + + @SerializedName("sha") + private String sha; + + @SerializedName("repo") + private Repository repository; + } + + @SuppressWarnings("ALL") + private static class Repository { + /** + * Example: "SonarSource/sonarqube" + */ + @SerializedName("full_name") + private String fullName; + + @SerializedName("owner") + private Owner owner; + } + + @SuppressWarnings("ALL") + private static class Owner { + /** + * The organization or user owning the repository. + * Example: "SonarSource" + */ + @SerializedName("name") + private String name; + /** + * Example: "https://api.github.com/repos/SonarSource/sonarqube" + */ + @SerializedName("url") + private String url; } } diff --git a/sonar-scanner-engine/src/main/resources/org/sonar/scanner/ci/providers/GithubActionsTest/pull_request_event.json b/sonar-scanner-engine/src/main/resources/org/sonar/scanner/ci/providers/GithubActionsTest/pull_request_event.json new file mode 100644 index 00000000000..2e8a39c2e3f --- /dev/null +++ b/sonar-scanner-engine/src/main/resources/org/sonar/scanner/ci/providers/GithubActionsTest/pull_request_event.json @@ -0,0 +1,448 @@ +{ + "action": "synchronize", + "after": "4aeb9d5d52f1b39cc7d17e4daf8bb6da2e1c55eb", + "before": "28c00f933d955d995639cb55db40274174ea0b00", + "number": 8, + "pull_request": { + "_links": { + "comments": { + "href": "https://api.github.com/repos/simonbrandhof/ci-tester/issues/8/comments" + }, + "commits": { + "href": "https://api.github.com/repos/simonbrandhof/ci-tester/pulls/8/commits" + }, + "html": { + "href": "https://github.com/simonbrandhof/ci-tester/pull/8" + }, + "issue": { + "href": "https://api.github.com/repos/simonbrandhof/ci-tester/issues/8" + }, + "review_comment": { + "href": "https://api.github.com/repos/simonbrandhof/ci-tester/pulls/comments{/number}" + }, + "review_comments": { + "href": "https://api.github.com/repos/simonbrandhof/ci-tester/pulls/8/comments" + }, + "self": { + "href": "https://api.github.com/repos/simonbrandhof/ci-tester/pulls/8" + }, + "statuses": { + "href": "https://api.github.com/repos/simonbrandhof/ci-tester/statuses/4aeb9d5d52f1b39cc7d17e4daf8bb6da2e1c55eb" + } + }, + "additions": 21, + "assignee": null, + "assignees": [], + "author_association": "OWNER", + "base": { + "label": "simonbrandhof:master", + "ref": "master", + "repo": { + "archive_url": "https://api.github.com/repos/simonbrandhof/ci-tester/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/simonbrandhof/ci-tester/assignees{/user}", + "blobs_url": "https://api.github.com/repos/simonbrandhof/ci-tester/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/simonbrandhof/ci-tester/branches{/branch}", + "clone_url": "https://github.com/simonbrandhof/ci-tester.git", + "collaborators_url": "https://api.github.com/repos/simonbrandhof/ci-tester/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/simonbrandhof/ci-tester/comments{/number}", + "commits_url": "https://api.github.com/repos/simonbrandhof/ci-tester/commits{/sha}", + "compare_url": "https://api.github.com/repos/simonbrandhof/ci-tester/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/simonbrandhof/ci-tester/contents/{+path}", + "contributors_url": "https://api.github.com/repos/simonbrandhof/ci-tester/contributors", + "created_at": "2017-05-08T09:05:32Z", + "default_branch": "master", + "deployments_url": "https://api.github.com/repos/simonbrandhof/ci-tester/deployments", + "description": null, + "disabled": false, + "downloads_url": "https://api.github.com/repos/simonbrandhof/ci-tester/downloads", + "events_url": "https://api.github.com/repos/simonbrandhof/ci-tester/events", + "fork": false, + "forks": 0, + "forks_count": 0, + "forks_url": "https://api.github.com/repos/simonbrandhof/ci-tester/forks", + "full_name": "simonbrandhof/ci-tester", + "git_commits_url": "https://api.github.com/repos/simonbrandhof/ci-tester/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/simonbrandhof/ci-tester/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/simonbrandhof/ci-tester/git/tags{/sha}", + "git_url": "git://github.com/simonbrandhof/ci-tester.git", + "has_downloads": true, + "has_issues": false, + "has_pages": false, + "has_projects": false, + "has_wiki": false, + "homepage": null, + "hooks_url": "https://api.github.com/repos/simonbrandhof/ci-tester/hooks", + "html_url": "https://github.com/simonbrandhof/ci-tester", + "id": 90607890, + "issue_comment_url": "https://api.github.com/repos/simonbrandhof/ci-tester/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/simonbrandhof/ci-tester/issues/events{/number}", + "issues_url": "https://api.github.com/repos/simonbrandhof/ci-tester/issues{/number}", + "keys_url": "https://api.github.com/repos/simonbrandhof/ci-tester/keys{/key_id}", + "labels_url": "https://api.github.com/repos/simonbrandhof/ci-tester/labels{/name}", + "language": "Java", + "languages_url": "https://api.github.com/repos/simonbrandhof/ci-tester/languages", + "license": null, + "merges_url": "https://api.github.com/repos/simonbrandhof/ci-tester/merges", + "milestones_url": "https://api.github.com/repos/simonbrandhof/ci-tester/milestones{/number}", + "mirror_url": null, + "name": "ci-tester", + "node_id": "MDEwOlJlcG9zaXRvcnk5MDYwNzg5MA==", + "notifications_url": "https://api.github.com/repos/simonbrandhof/ci-tester/notifications{?since,all,participating}", + "open_issues": 5, + "open_issues_count": 5, + "owner": { + "avatar_url": "https://avatars1.githubusercontent.com/u/414010?v=4", + "events_url": "https://api.github.com/users/simonbrandhof/events{/privacy}", + "followers_url": "https://api.github.com/users/simonbrandhof/followers", + "following_url": "https://api.github.com/users/simonbrandhof/following{/other_user}", + "gists_url": "https://api.github.com/users/simonbrandhof/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/simonbrandhof", + "id": 414010, + "login": "simonbrandhof", + "node_id": "MDQ6VXNlcjQxNDAxMA==", + "organizations_url": "https://api.github.com/users/simonbrandhof/orgs", + "received_events_url": "https://api.github.com/users/simonbrandhof/received_events", + "repos_url": "https://api.github.com/users/simonbrandhof/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/simonbrandhof/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/simonbrandhof/subscriptions", + "type": "User", + "url": "https://api.github.com/users/simonbrandhof" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/simonbrandhof/ci-tester/pulls{/number}", + "pushed_at": "2019-05-30T18:57:05Z", + "releases_url": "https://api.github.com/repos/simonbrandhof/ci-tester/releases{/id}", + "size": 86, + "ssh_url": "git@github.com:simonbrandhof/ci-tester.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/simonbrandhof/ci-tester/stargazers", + "statuses_url": "https://api.github.com/repos/simonbrandhof/ci-tester/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/simonbrandhof/ci-tester/subscribers", + "subscription_url": "https://api.github.com/repos/simonbrandhof/ci-tester/subscription", + "svn_url": "https://github.com/simonbrandhof/ci-tester", + "tags_url": "https://api.github.com/repos/simonbrandhof/ci-tester/tags", + "teams_url": "https://api.github.com/repos/simonbrandhof/ci-tester/teams", + "trees_url": "https://api.github.com/repos/simonbrandhof/ci-tester/git/trees{/sha}", + "updated_at": "2019-05-22T16:32:37Z", + "url": "https://api.github.com/repos/simonbrandhof/ci-tester", + "watchers": 0, + "watchers_count": 0 + }, + "sha": "d9c8272a5d52856ebef01507484893239e3457dd", + "user": { + "avatar_url": "https://avatars1.githubusercontent.com/u/414010?v=4", + "events_url": "https://api.github.com/users/simonbrandhof/events{/privacy}", + "followers_url": "https://api.github.com/users/simonbrandhof/followers", + "following_url": "https://api.github.com/users/simonbrandhof/following{/other_user}", + "gists_url": "https://api.github.com/users/simonbrandhof/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/simonbrandhof", + "id": 414010, + "login": "simonbrandhof", + "node_id": "MDQ6VXNlcjQxNDAxMA==", + "organizations_url": "https://api.github.com/users/simonbrandhof/orgs", + "received_events_url": "https://api.github.com/users/simonbrandhof/received_events", + "repos_url": "https://api.github.com/users/simonbrandhof/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/simonbrandhof/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/simonbrandhof/subscriptions", + "type": "User", + "url": "https://api.github.com/users/simonbrandhof" + } + }, + "body": "", + "changed_files": 7, + "closed_at": null, + "comments": 0, + "comments_url": "https://api.github.com/repos/simonbrandhof/ci-tester/issues/8/comments", + "commits": 12, + "commits_url": "https://api.github.com/repos/simonbrandhof/ci-tester/pulls/8/commits", + "created_at": "2019-05-30T17:23:00Z", + "deletions": 42, + "diff_url": "https://github.com/simonbrandhof/ci-tester/pull/8.diff", + "draft": false, + "head": { + "label": "simonbrandhof:foo", + "ref": "foo", + "repo": { + "archive_url": "https://api.github.com/repos/simonbrandhof/ci-tester/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/simonbrandhof/ci-tester/assignees{/user}", + "blobs_url": "https://api.github.com/repos/simonbrandhof/ci-tester/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/simonbrandhof/ci-tester/branches{/branch}", + "clone_url": "https://github.com/simonbrandhof/ci-tester.git", + "collaborators_url": "https://api.github.com/repos/simonbrandhof/ci-tester/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/simonbrandhof/ci-tester/comments{/number}", + "commits_url": "https://api.github.com/repos/simonbrandhof/ci-tester/commits{/sha}", + "compare_url": "https://api.github.com/repos/simonbrandhof/ci-tester/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/simonbrandhof/ci-tester/contents/{+path}", + "contributors_url": "https://api.github.com/repos/simonbrandhof/ci-tester/contributors", + "created_at": "2017-05-08T09:05:32Z", + "default_branch": "master", + "deployments_url": "https://api.github.com/repos/simonbrandhof/ci-tester/deployments", + "description": null, + "disabled": false, + "downloads_url": "https://api.github.com/repos/simonbrandhof/ci-tester/downloads", + "events_url": "https://api.github.com/repos/simonbrandhof/ci-tester/events", + "fork": false, + "forks": 0, + "forks_count": 0, + "forks_url": "https://api.github.com/repos/simonbrandhof/ci-tester/forks", + "full_name": "simonbrandhof/ci-tester", + "git_commits_url": "https://api.github.com/repos/simonbrandhof/ci-tester/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/simonbrandhof/ci-tester/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/simonbrandhof/ci-tester/git/tags{/sha}", + "git_url": "git://github.com/simonbrandhof/ci-tester.git", + "has_downloads": true, + "has_issues": false, + "has_pages": false, + "has_projects": false, + "has_wiki": false, + "homepage": null, + "hooks_url": "https://api.github.com/repos/simonbrandhof/ci-tester/hooks", + "html_url": "https://github.com/simonbrandhof/ci-tester", + "id": 90607890, + "issue_comment_url": "https://api.github.com/repos/simonbrandhof/ci-tester/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/simonbrandhof/ci-tester/issues/events{/number}", + "issues_url": "https://api.github.com/repos/simonbrandhof/ci-tester/issues{/number}", + "keys_url": "https://api.github.com/repos/simonbrandhof/ci-tester/keys{/key_id}", + "labels_url": "https://api.github.com/repos/simonbrandhof/ci-tester/labels{/name}", + "language": "Java", + "languages_url": "https://api.github.com/repos/simonbrandhof/ci-tester/languages", + "license": null, + "merges_url": "https://api.github.com/repos/simonbrandhof/ci-tester/merges", + "milestones_url": "https://api.github.com/repos/simonbrandhof/ci-tester/milestones{/number}", + "mirror_url": null, + "name": "ci-tester", + "node_id": "MDEwOlJlcG9zaXRvcnk5MDYwNzg5MA==", + "notifications_url": "https://api.github.com/repos/simonbrandhof/ci-tester/notifications{?since,all,participating}", + "open_issues": 5, + "open_issues_count": 5, + "owner": { + "avatar_url": "https://avatars1.githubusercontent.com/u/414010?v=4", + "events_url": "https://api.github.com/users/simonbrandhof/events{/privacy}", + "followers_url": "https://api.github.com/users/simonbrandhof/followers", + "following_url": "https://api.github.com/users/simonbrandhof/following{/other_user}", + "gists_url": "https://api.github.com/users/simonbrandhof/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/simonbrandhof", + "id": 414010, + "login": "simonbrandhof", + "node_id": "MDQ6VXNlcjQxNDAxMA==", + "organizations_url": "https://api.github.com/users/simonbrandhof/orgs", + "received_events_url": "https://api.github.com/users/simonbrandhof/received_events", + "repos_url": "https://api.github.com/users/simonbrandhof/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/simonbrandhof/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/simonbrandhof/subscriptions", + "type": "User", + "url": "https://api.github.com/users/simonbrandhof" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/simonbrandhof/ci-tester/pulls{/number}", + "pushed_at": "2019-05-30T18:57:05Z", + "releases_url": "https://api.github.com/repos/simonbrandhof/ci-tester/releases{/id}", + "size": 86, + "ssh_url": "git@github.com:simonbrandhof/ci-tester.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/simonbrandhof/ci-tester/stargazers", + "statuses_url": "https://api.github.com/repos/simonbrandhof/ci-tester/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/simonbrandhof/ci-tester/subscribers", + "subscription_url": "https://api.github.com/repos/simonbrandhof/ci-tester/subscription", + "svn_url": "https://github.com/simonbrandhof/ci-tester", + "tags_url": "https://api.github.com/repos/simonbrandhof/ci-tester/tags", + "teams_url": "https://api.github.com/repos/simonbrandhof/ci-tester/teams", + "trees_url": "https://api.github.com/repos/simonbrandhof/ci-tester/git/trees{/sha}", + "updated_at": "2019-05-22T16:32:37Z", + "url": "https://api.github.com/repos/simonbrandhof/ci-tester", + "watchers": 0, + "watchers_count": 0 + }, + "sha": "4aeb9d5d52f1b39cc7d17e4daf8bb6da2e1c55eb", + "user": { + "avatar_url": "https://avatars1.githubusercontent.com/u/414010?v=4", + "events_url": "https://api.github.com/users/simonbrandhof/events{/privacy}", + "followers_url": "https://api.github.com/users/simonbrandhof/followers", + "following_url": "https://api.github.com/users/simonbrandhof/following{/other_user}", + "gists_url": "https://api.github.com/users/simonbrandhof/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/simonbrandhof", + "id": 414010, + "login": "simonbrandhof", + "node_id": "MDQ6VXNlcjQxNDAxMA==", + "organizations_url": "https://api.github.com/users/simonbrandhof/orgs", + "received_events_url": "https://api.github.com/users/simonbrandhof/received_events", + "repos_url": "https://api.github.com/users/simonbrandhof/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/simonbrandhof/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/simonbrandhof/subscriptions", + "type": "User", + "url": "https://api.github.com/users/simonbrandhof" + } + }, + "html_url": "https://github.com/simonbrandhof/ci-tester/pull/8", + "id": 283739908, + "issue_url": "https://api.github.com/repos/simonbrandhof/ci-tester/issues/8", + "labels": [], + "locked": false, + "maintainer_can_modify": false, + "merge_commit_sha": "7171548ab96a48dc5bc5bc04f8f0e54f02e7ea8e", + "mergeable": null, + "mergeable_state": "unknown", + "merged": false, + "merged_at": null, + "merged_by": null, + "milestone": null, + "node_id": "MDExOlB1bGxSZXF1ZXN0MjgzNzM5OTA4", + "number": 8, + "patch_url": "https://github.com/simonbrandhof/ci-tester/pull/8.patch", + "rebaseable": null, + "requested_reviewers": [], + "requested_teams": [], + "review_comment_url": "https://api.github.com/repos/simonbrandhof/ci-tester/pulls/comments{/number}", + "review_comments": 0, + "review_comments_url": "https://api.github.com/repos/simonbrandhof/ci-tester/pulls/8/comments", + "state": "open", + "statuses_url": "https://api.github.com/repos/simonbrandhof/ci-tester/statuses/4aeb9d5d52f1b39cc7d17e4daf8bb6da2e1c55eb", + "title": "Test Github Actions", + "updated_at": "2019-05-30T18:57:06Z", + "url": "https://api.github.com/repos/simonbrandhof/ci-tester/pulls/8", + "user": { + "avatar_url": "https://avatars1.githubusercontent.com/u/414010?v=4", + "events_url": "https://api.github.com/users/simonbrandhof/events{/privacy}", + "followers_url": "https://api.github.com/users/simonbrandhof/followers", + "following_url": "https://api.github.com/users/simonbrandhof/following{/other_user}", + "gists_url": "https://api.github.com/users/simonbrandhof/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/simonbrandhof", + "id": 414010, + "login": "simonbrandhof", + "node_id": "MDQ6VXNlcjQxNDAxMA==", + "organizations_url": "https://api.github.com/users/simonbrandhof/orgs", + "received_events_url": "https://api.github.com/users/simonbrandhof/received_events", + "repos_url": "https://api.github.com/users/simonbrandhof/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/simonbrandhof/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/simonbrandhof/subscriptions", + "type": "User", + "url": "https://api.github.com/users/simonbrandhof" + } + }, + "repository": { + "archive_url": "https://api.github.com/repos/simonbrandhof/ci-tester/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/simonbrandhof/ci-tester/assignees{/user}", + "blobs_url": "https://api.github.com/repos/simonbrandhof/ci-tester/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/simonbrandhof/ci-tester/branches{/branch}", + "clone_url": "https://github.com/simonbrandhof/ci-tester.git", + "collaborators_url": "https://api.github.com/repos/simonbrandhof/ci-tester/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/simonbrandhof/ci-tester/comments{/number}", + "commits_url": "https://api.github.com/repos/simonbrandhof/ci-tester/commits{/sha}", + "compare_url": "https://api.github.com/repos/simonbrandhof/ci-tester/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/simonbrandhof/ci-tester/contents/{+path}", + "contributors_url": "https://api.github.com/repos/simonbrandhof/ci-tester/contributors", + "created_at": "2017-05-08T09:05:32Z", + "default_branch": "master", + "deployments_url": "https://api.github.com/repos/simonbrandhof/ci-tester/deployments", + "description": null, + "disabled": false, + "downloads_url": "https://api.github.com/repos/simonbrandhof/ci-tester/downloads", + "events_url": "https://api.github.com/repos/simonbrandhof/ci-tester/events", + "fork": false, + "forks": 0, + "forks_count": 0, + "forks_url": "https://api.github.com/repos/simonbrandhof/ci-tester/forks", + "full_name": "simonbrandhof/ci-tester", + "git_commits_url": "https://api.github.com/repos/simonbrandhof/ci-tester/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/simonbrandhof/ci-tester/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/simonbrandhof/ci-tester/git/tags{/sha}", + "git_url": "git://github.com/simonbrandhof/ci-tester.git", + "has_downloads": true, + "has_issues": false, + "has_pages": false, + "has_projects": false, + "has_wiki": false, + "homepage": null, + "hooks_url": "https://api.github.com/repos/simonbrandhof/ci-tester/hooks", + "html_url": "https://github.com/simonbrandhof/ci-tester", + "id": 90607890, + "issue_comment_url": "https://api.github.com/repos/simonbrandhof/ci-tester/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/simonbrandhof/ci-tester/issues/events{/number}", + "issues_url": "https://api.github.com/repos/simonbrandhof/ci-tester/issues{/number}", + "keys_url": "https://api.github.com/repos/simonbrandhof/ci-tester/keys{/key_id}", + "labels_url": "https://api.github.com/repos/simonbrandhof/ci-tester/labels{/name}", + "language": "Java", + "languages_url": "https://api.github.com/repos/simonbrandhof/ci-tester/languages", + "license": null, + "merges_url": "https://api.github.com/repos/simonbrandhof/ci-tester/merges", + "milestones_url": "https://api.github.com/repos/simonbrandhof/ci-tester/milestones{/number}", + "mirror_url": null, + "name": "ci-tester", + "node_id": "MDEwOlJlcG9zaXRvcnk5MDYwNzg5MA==", + "notifications_url": "https://api.github.com/repos/simonbrandhof/ci-tester/notifications{?since,all,participating}", + "open_issues": 5, + "open_issues_count": 5, + "owner": { + "avatar_url": "https://avatars1.githubusercontent.com/u/414010?v=4", + "events_url": "https://api.github.com/users/simonbrandhof/events{/privacy}", + "followers_url": "https://api.github.com/users/simonbrandhof/followers", + "following_url": "https://api.github.com/users/simonbrandhof/following{/other_user}", + "gists_url": "https://api.github.com/users/simonbrandhof/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/simonbrandhof", + "id": 414010, + "login": "simonbrandhof", + "node_id": "MDQ6VXNlcjQxNDAxMA==", + "organizations_url": "https://api.github.com/users/simonbrandhof/orgs", + "received_events_url": "https://api.github.com/users/simonbrandhof/received_events", + "repos_url": "https://api.github.com/users/simonbrandhof/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/simonbrandhof/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/simonbrandhof/subscriptions", + "type": "User", + "url": "https://api.github.com/users/simonbrandhof" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/simonbrandhof/ci-tester/pulls{/number}", + "pushed_at": "2019-05-30T18:57:05Z", + "releases_url": "https://api.github.com/repos/simonbrandhof/ci-tester/releases{/id}", + "size": 86, + "ssh_url": "git@github.com:simonbrandhof/ci-tester.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/simonbrandhof/ci-tester/stargazers", + "statuses_url": "https://api.github.com/repos/simonbrandhof/ci-tester/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/simonbrandhof/ci-tester/subscribers", + "subscription_url": "https://api.github.com/repos/simonbrandhof/ci-tester/subscription", + "svn_url": "https://github.com/simonbrandhof/ci-tester", + "tags_url": "https://api.github.com/repos/simonbrandhof/ci-tester/tags", + "teams_url": "https://api.github.com/repos/simonbrandhof/ci-tester/teams", + "trees_url": "https://api.github.com/repos/simonbrandhof/ci-tester/git/trees{/sha}", + "updated_at": "2019-05-22T16:32:37Z", + "url": "https://api.github.com/repos/simonbrandhof/ci-tester", + "watchers": 0, + "watchers_count": 0 + }, + "sender": { + "avatar_url": "https://avatars1.githubusercontent.com/u/414010?v=4", + "events_url": "https://api.github.com/users/simonbrandhof/events{/privacy}", + "followers_url": "https://api.github.com/users/simonbrandhof/followers", + "following_url": "https://api.github.com/users/simonbrandhof/following{/other_user}", + "gists_url": "https://api.github.com/users/simonbrandhof/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/simonbrandhof", + "id": 414010, + "login": "simonbrandhof", + "node_id": "MDQ6VXNlcjQxNDAxMA==", + "organizations_url": "https://api.github.com/users/simonbrandhof/orgs", + "received_events_url": "https://api.github.com/users/simonbrandhof/received_events", + "repos_url": "https://api.github.com/users/simonbrandhof/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/simonbrandhof/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/simonbrandhof/subscriptions", + "type": "User", + "url": "https://api.github.com/users/simonbrandhof" + } +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/GithubActionsTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/GithubActionsTest.java index 13840db05f1..4619f3918f2 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/GithubActionsTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/GithubActionsTest.java @@ -19,69 +19,93 @@ */ package org.sonar.scanner.ci.vendors; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Objects; import javax.annotation.Nullable; -import org.junit.Rule; -import org.junit.Test; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.io.TempDir; import org.slf4j.event.Level; -import org.sonar.api.testfixtures.log.LogTester; +import org.sonar.api.testfixtures.log.LogTesterJUnit5; import org.sonar.api.utils.System2; import org.sonar.scanner.ci.CiConfiguration; import org.sonar.scanner.ci.CiVendor; import org.sonar.scanner.ci.DevOpsPlatformInfo; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import static org.sonar.scanner.ci.vendors.GithubActions.GITHUB_ACTION; +import static org.sonar.scanner.ci.vendors.GithubActions.GITHUB_API_URL_ENV_VAR; +import static org.sonar.scanner.ci.vendors.GithubActions.GITHUB_EVENT_NAME; +import static org.sonar.scanner.ci.vendors.GithubActions.GITHUB_EVENT_PATH; +import static org.sonar.scanner.ci.vendors.GithubActions.GITHUB_REPOSITORY_ENV_VAR; +import static org.sonar.scanner.ci.vendors.GithubActions.GITHUB_SHA; -public class GithubActionsTest { +class GithubActionsTest { private static final String GITHUB_API_URL = "https://api.github.com/"; private static final String REPOSITORY = "foo/bar"; - @Rule - public LogTester logs = new LogTester(); + @RegisterExtension + private final LogTesterJUnit5 logs = new LogTesterJUnit5(); + @TempDir + public Path temp; - private System2 system = mock(System2.class); - private CiVendor underTest = new GithubActions(system); + private final System2 system = mock(System2.class); + private final CiVendor underTest = new GithubActions(system); @Test - public void getName() { + void getName() { assertThat(underTest.getName()).isEqualTo("Github Actions"); } @Test - public void isDetected() { - setEnvVariable("GITHUB_ACTION", "build"); + void isDetected() { + setEnvVariable(GITHUB_ACTION, "build"); assertThat(underTest.isDetected()).isTrue(); - setEnvVariable("GITHUB_ACTION", null); + setEnvVariable(GITHUB_ACTION, null); assertThat(underTest.isDetected()).isFalse(); } @Test - public void loadConfiguration() { - setEnvVariable("GITHUB_ACTION", "build"); - setEnvVariable("GITHUB_SHA", "abd12fc"); - setEnvVariable("GITHUB_API_URL", GITHUB_API_URL); - setEnvVariable("GITHUB_REPOSITORY", REPOSITORY); + void loadConfiguration_whenIsAPullRequest_ThenGetRevisionFromPullRequest() throws IOException { + prepareEvent("org/sonar/scanner/ci/providers/GithubActionsTest/pull_request_event.json", "pull_request"); + setEnvVariable(GITHUB_SHA, "abd12fc"); + setEnvVariable(GITHUB_API_URL_ENV_VAR, GITHUB_API_URL); + setEnvVariable(GITHUB_REPOSITORY_ENV_VAR, REPOSITORY); CiConfiguration configuration = underTest.loadConfiguration(); - assertThat(configuration.getScmRevision()).hasValue("abd12fc"); + assertThat(configuration.getScmRevision()).hasValue("4aeb9d5d52f1b39cc7d17e4daf8bb6da2e1c55eb"); checkDevOpsPlatformInfo(configuration); } @Test - public void log_warning_if_missing_GITHUB_SHA() { - setEnvVariable("GITHUB_ACTION", "build"); + void loadConfiguration_whenIsNotAPullRequest_ThenGetRevisionFromEnvVar() { + setEnvVariable(GITHUB_SHA, "abd12fc"); + setEnvVariable(GITHUB_API_URL_ENV_VAR, GITHUB_API_URL); + setEnvVariable(GITHUB_REPOSITORY_ENV_VAR, REPOSITORY); + + CiConfiguration configuration = underTest.loadConfiguration(); + assertThat(configuration.getScmRevision()).hasValue("abd12fc"); + checkDevOpsPlatformInfo(configuration); + } + @Test + void log_warning_if_missing_GITHUB_SHA() { assertThat(underTest.loadConfiguration().getScmRevision()).isEmpty(); assertThat(logs.logs(Level.WARN)).contains("Missing environment variable GITHUB_SHA"); } @Test - public void loadConfiguration_whenMissingGitHubEnvironmentVariables_shouldLogWarn() { - setEnvVariable("GITHUB_ACTION", "build"); - + void loadConfiguration_whenMissingGitHubEnvironmentVariables_shouldLogWarn() { assertThat(underTest.loadConfiguration().getDevOpsPlatformInfo()).isEmpty(); assertThat(logs.logs(Level.WARN)).contains("Missing or empty environment variables: GITHUB_API_URL, and/or GITHUB_REPOSITORY"); } @@ -95,6 +119,18 @@ public class GithubActionsTest { DevOpsPlatformInfo devOpsPlatformInfo = configuration.getDevOpsPlatformInfo().get(); assertThat(devOpsPlatformInfo.getProjectIdentifier()).isEqualTo(REPOSITORY); assertThat(devOpsPlatformInfo.getUrl()).isEqualTo(GITHUB_API_URL); + } + + private void prepareEvent(String jsonFilename, String eventName) throws IOException { + File tempFile = Files.createFile(temp.resolve("file.json")).toFile(); + String json = readTestResource(jsonFilename); + FileUtils.write(tempFile, json, UTF_8); + + setEnvVariable(GITHUB_EVENT_PATH, tempFile.getAbsolutePath()); + setEnvVariable(GITHUB_EVENT_NAME, eventName); + } + private static String readTestResource(String filename) throws IOException { + return IOUtils.toString(Objects.requireNonNull(GithubActionsTest.class.getClassLoader().getResource(filename)), UTF_8); } } |