trautonen / coveralls-maven-plugin

Maven plugin for submitting Java code coverage reports to Coveralls web service.
MIT License
312 stars 123 forks source link

Support github actions as service #136

Open TheSnoozer opened 4 years ago

TheSnoozer commented 4 years ago

Similar to all other services (e.g. the jenkins service), there should be a service that supports github actions.

Environment variables are documented in https://help.github.com/en/actions/automating-your-workflow-with-github-actions/using-environment-variables#default-environment-variables

Untested:

public class GithubAction extends AbstractServiceSetup {

    public static final String GITHUB_ACTION_NAME = "githubaction";
    public static final String GITHUB_ACTIONS = "GITHUB_ACTIONS";
    public static final String GITHUB_ACTION_BUILD_NUMBER = "GITHUB_ACTION";
    public static final String GITHUB_ACTION_BUILD_URL = "GITHUB_REPOSITORY";
    public static final String GITHUB_ACTION_BRANCH = "GITHUB_REF";
    public static final String GITHUB_ACTION_COMMIT = "GITHUB_SHA";

    public Jenkins(final Map<String, String> env) {
        super(env);
    }

    @Override
    public boolean isSelected() {
        return (getProperty(GITHUB_ACTIONS) != null);
    }

    @Override
    public String getName() {
        return GITHUB_ACTION_NAME;
    }

    @Override
    public String getBuildNumber() {
        return getProperty(GITHUB_ACTION_BUILD_NUMBER);
    }

    @Override
    public String getBuildUrl() {
        // TODO: do we need https://github.com here?
        return getProperty(GITHUB_ACTION_BUILD_URL);
    }

    @Override
    public String getBranch() {
        // TODO: this looks like "refs/heads/feature-branch-1" and might be empty - does this mean null?
        return getProperty(GITHUB_ACTION_BRANCH);
    }

    @Override
    public Properties getEnvironment() {
        Properties environment = new Properties();
        addProperty(environment, "github_action_build_num", getBuildNumber());
        addProperty(environment, "github_action_build_url", getBuildUrl());
        addProperty(environment, "branch", getBranch());
        addProperty(environment, "commit_sha", getProperty(GITHUB_ACTION_COMMIT));
        return environment;
    }
}
TheSnoozer commented 4 years ago

Note: When running mvn clean test jacoco:report coveralls:report -Pcoveralls -DrepoToken=${COVERALLS_REPO_TOKEN} -B the repo seems to be in detached head and results in the corresponding git-commit as branch (see https://coveralls.io/github/git-commit-id/maven-git-commit-id-plugin?branch=76c219f27db4825051d35576d61a915c12937475). A workaround might be to also specify the branch property.

There is also a "coverallsapp" for github actions (https://github.com/coverallsapp/github-action/), but this does not allow my use-case.

abelsromero commented 4 years ago

Any changes of this being merged? I am too interesting in pushing from GitHub actions

derekm commented 4 years ago

Here's a run action that provides a consistent way to get the branch name for both push & pull_request event types:

    - env:
        BRANCH_NAME_OR_REF: ${{ github.head_ref || github.ref }}
      run: echo "::set-env name=BRANCH_NAME::${BRANCH_NAME_OR_REF#refs/heads/}"

You can use this pattern to implement a correct getBranch() method above.

derekm commented 4 years ago

@TheSnoozer --

Note: ... the repo seems to be in detached head and results in the corresponding git-commit as branch... A workaround might be to also specify the branch property.

Specifying the branch property doesn't seem to work for me. See, for example, my run action to execute the Coveralls Maven plugin:

    - name: Coveralls Maven plugin
      run: |
        mvn coveralls:report \
        --no-transfer-progress \
        -D repoToken=${{ secrets.COVERALLS_TOKEN }} \
        -D serviceName=Github \
        -D serviceBuildUrl=https://github.com/${{ github.repository }}/commit/${{ github.sha }}/checks \
        -D branch=$BRANCH_NAME \
        -D pullRequest=$PR_NUMBER

Even though $BRANCH_NAME is master, over on the coveralls website, I still get commit hash for branch name. See here: https://coveralls.io/builds/32356781

abelsromero commented 4 years ago

For anyone interested, there's still the problem of PR from forks. GitHub actions do no publish secrets on PR, so any solution only works for branches on the main repo. In my case, we opted to have a TravisCI job only for that.

derekm commented 4 years ago

I finally got coveralls-maven-plugin to publish the master branch name by passing the information along using CI_* environment variables instead of command line arguments (or using set-output instead of set-env to extract the branch name & PR number).

See here: https://github.com/derekm/pravega-cdi/commit/2ca6cd388b1fe9f83b4fb98b7e70e35c30818cbc Or:

    - name: Set branch name and PR number
      id: refs
      env:
        BRANCH_NAME_OR_REF: ${{ github.head_ref || github.ref }}
      run: |
        echo "::set-output name=branch_name::${BRANCH_NAME_OR_REF#refs/heads/}"
        echo "::set-output name=pr_number::$(jq --raw-output .pull_request.number "$GITHUB_EVENT_PATH")"
    - name: Coveralls Maven plugin
      env:
        CI_NAME: Github
        CI_BUILD_NUMBER: ${{ github.run_id }}
        CI_BUILD_URL: https://github.com/${{ github.repository }}/commit/${{ github.event.after }}/checks
        CI_BRANCH: ${{ steps.refs.outputs.branch_name }}
        CI_PULL_REQUEST: ${{ steps.refs.outputs.pr_number }}
      run: |
        mvn coveralls:report \
        --no-transfer-progress \
        -D repoToken=${{ secrets.COVERALLS_TOKEN }}

I see, @abelsromero. That does present a problem in upstream PRs. I've been testing with PRs back into my own fork, and it is using my secrets. This must be why the project I work on has their tokens in their travis.yml file!

dkfellows commented 3 years ago

I've been testing this further; you need two things critically:

That combination works (at least for PRs submitted within my team based on commits to branches in the main repo, which is what I care about especially). I was using exactly this workflow step to do it, with no preparatory steps (they're rolled into this one):

- name: "Report: Coverage via coveralls.io"
  run: |
    export CI_BRANCH=${BRANCH_NAME_OR_REF#refs/heads/}
    export CI_PULL_REQUEST=$(jq --raw-output .pull_request.number "$GITHUB_EVENT_PATH")
    mvn coveralls:report --settings $SETTINGS_FILE --no-transfer-progress -DrepoToken=$COVERALLS_SECRET
  env:
    CI_NAME: github
    BRANCH_NAME_OR_REF: ${{ github.head_ref || github.ref }}
    CI_BUILD_NUMBER: ${{ github.run_id }}
    CI_BUILD_URL: https://github.com/${{ github.repository }}/commit/${{ github.event.after }}/checks
    COVERALLS_SECRET: ${{ secrets.GITHUB_TOKEN }}

You might not want the --settings $SETTINGS_FILE bit. (I use it to control plugin downloading.)

davidjgonzalez commented 3 years ago

@dkfellows - So the -DrepoToken needs to be the Github token and NOT the Coveralls Repo Token (that you get from coveralls.io ?)

poikilotherm commented 3 years ago

Shout out to @Anushka-shukla for providing a working solution for pull requests.

@davidjgonzalez : yes, it's the Github Token that's needed. @dkfellows : thanks for providing a more extensive example. Might come back to this.

kwin commented 3 years ago

The parameter repoToken is the Coveralls Repo Token (https://github.com/trautonen/coveralls-maven-plugin/blob/8b8995e42768a25c8db6e85ede62238bf4606cb2/src/main/java/org/eluder/coveralls/maven/plugin/json/JsonWriter.java#L77 and https://docs.coveralls.io/api-introduction). But nowadays Coveralls supports tokenless authentication: https://github.com/codecov/codecov-action/issues/29#issuecomment-595288709.

The coveralls-action uses this bash script to construct the API Request URL for Github Actions: https://github.com/codecov/codecov-action/blob/d1f4b0126d40ebac033c5535c8ac351c25c441ea/codecov#L848

Not sure how to construct the same URL with the Maven plugin yet.