Giter VIP home page Giter VIP logo

reviewpad's Introduction

This project is now in maintenance mode. Please feel free to fork the project to apply any changes you might want to make.

Reviewpad

Reviewpad

x-ray-badge Build Go Report Card

Welcome to Reviewpad!

For questions, check out the GitHub discussions.

For documentation, check out this document and the official documentation.

Join our community on Discord!

To start using Reviewpad, check out our website.

What is Reviewpad?

Reviewpad is a service to automate pull requests and issues workflows.

The workflows are specified in a YML-based configuration language described in the official documentation.

In Reviewpad, you can automate actions over the pull requests and issues such as:

  1. Automated comments;
  2. Add or remove labels;
  3. Specify reviewer assignments;
  4. Automate close/merge actions;
  5. Block the merge action;
  6. Automatically summarize pull requests;

As an example, the following workflow:

labels:
  ship:
    description: Ship mode
    color: "#76dbbe"

workflows:
  - name: ship
    description: Ship process - bypass the review and merge with rebase
    run:
      - if: $hasFileExtensions([".md"])
        then:
          - $addLabel("ship")
          - $merge()

Automatically adds the label ship and merges all pull requests that only change .md files.

You can execute Reviewpad through the CLI or install Reviewpad GitHub App.

Architecture

This repository generates two artifacts:

  1. CLI cli that runs Reviewpad open source edition.
  2. Reviewpad library packages:
    • github.com/reviewpad/reviewpad/collector
    • github.com/reviewpad/reviewpad/engine
    • github.com/reviewpad/reviewpad/lang/aladino
    • github.com/reviewpad/reviewpad/plugins/aladino
    • github.com/reviewpad/reviewpad/utils

Conceptually, the packages are divided into four categories:

  1. Engine: The engine is the package responsible for processing the YML file. This process is divided into two stages:
    • Process the YML file to determine which workflows are enabled. The outcome of this phase is a program with the actions that will be executed over the pull request.
    • Execution of the synthesised program.
  2. Aladino Language: This is the language that is used in the spec property of the rules and also the actions of the workflows. The engine of Reviewpad is not specific to Aladino - this means that it is possible to add support for a new language such as Javascript or Golang in these specifications.
  3. Plugins: The plugin package contains the built-in functions and actions that act as an abstraction to the 3rd party services such as GitHub, Jira, etc. This package is specific to each supported specification language. In the case of plugins/aladino, it contains the implementations of the built-ins.
  4. Utilities: packages, such as the collector, that provide utilities that are used in multiple places.

Development

Prerequisites

Before you begin, ensure you have met the following requirements:

  • Go with the minimum version of 1.16.
  • goyacc used to generate Reviewpad Aladino parser (go install golang.org/x/tools/cmd/goyacc@master).
  • libgit2 with version v1.2.
  • To run the tests, Reviewpad requires the following environment variables:
    • INPUT_SEMANTIC_SERVICE. You can do this by running the following command in your terminal: export INPUT_SEMANTIC_SERVICE="0.0.0.0:3006".
    • INPUT_ROBIN_SERVICE. You can do this by running the following command in your terminal: export INPUT_ROBIN_SERVICE="0.0.0.0:3011".
    • INPUT_CODEHOST_SERVICE. You can do this by running the following command in your terminal: export INPUT_CODEHOST_SERVICE="0.0.0.0:3004".

Compilation

We use Taskfile. To compile the packages simply run:

task build

To generate the CLI run:

task build-cli

This command generates the binary reviewpad-cli which you can run to try Reviewpad directly.

The CLI has the following argument list:

./reviewpad-cli
reviewpad-cli is command line interface to run reviewpad commands.

Usage:
  reviewpad-cli [command]

Available Commands:
  check       Check if input reviewpad file is valid
  completion  Generate the autocompletion script for the specified shell
  help        Help about any command
  run         Runs reviewpad

Flags:
  -f, --file string   input reviewpad file
  -h, --help          help for reviewpad-cli

Use "reviewpad-cli [command] --help" for more information about a command.

Running unit tests

Run the tests with:

task test

If you get the error:

panic: httptest: failed to listen on a port: listen tcp6 [::1]:0: socket: too many open files [recovered]
        panic: httptest: failed to listen on a port: listen tcp6 [::1]:0: socket: too many open files

You can solve with:

ulimit -Sn 500

Coverage

To generate the coverage report run:

task test

To display the code coverage for every package run:

go tool cover -func coverage.out

To display the total code coverage percentage run:

go tool cover -func coverage.out | grep total:

Running integration tests

The integration tests run Reviewpad on an actual repository and pull request. The repository where the integration tests run requires the following setup:

  • At least one milestone;
  • At least 3 labels named bug, documentation, wontfix (GitHub adds these labels to every new repository by default);
  • A team called integration-test with at least 3 members;
  • A project called [INTEGRATION TESTS] Reviewpad with Todo and In Progress status
  • A GitHub status check called log event.

Required Environment Variables

  • GITHUB_INTEGRATION_TEST_TOKEN : GitHub access token used to setup tests and run Reviewpad
  • GITHUB_INTEGRATION_TEST_REPO_OWNER : The owner of the repository used to run integration tests on
  • GITHUB_INTEGRATION_TEST_REPO_NAME : The name of the repository used to run integration tests on

After setting these variables, you can run the integration tests with:

task integration-test

VSCode

We strongly recommend using VSCode with the following extensions:

Open the project in VSCode, open the command palette (Ctrl+Shift+P) and search for Preferences: Open Workspace Settings (JSON).

Paste the following configuration:

{
    // Licenser configuration
    "licenser.license": "Custom",
    "licenser.author": "Explore.dev, Unipessoal Lda",
    "licenser.customHeader": "Copyright (C) @YEAR@ @AUTHOR@ - All Rights Reserved\nUse of this source code is governed by a license that can be\nfound in the LICENSE file.",
    // Associate Reviewpad schema to reviewpad.(yml|yaml) files
    "yaml.schemas": {
        "https://raw.githubusercontent.com/reviewpad/schemas/main/latest/schema.json": [
            "reviewpad.yml",
        ]
    },
    // Go configuration
    "go.testFlags": [
        "integration"
    ],
    "go.buildFlags": [
        "-tags=integration"
    ],
}

Debugging with VSCode

Add the following to your .vscode/launch.json.

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch CLI",
            "type": "go",
            "request": "launch",
            "mode": "debug",
            "args": [
                "run",
                // Flag to run on dry run (optional. Default is false)
                "-d",
                // Flag to run on safe mode (optional. Default is false)
                "-s",
                // Flag to define the log level (optional. Default is debug)
                "-l=debug",
                // GiHub personal access token.
                // To generate a token, go to https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token.
                "-t=<GIT_HUB_TOKEN>",
                // Absolute path to reviewpad.yml file to run.
                "-f=<PATH_TO_REVIEWPAD_FILE>",
                // GitHub URL of the pull request / issue.
                // The reviewpad.yml file provided with the -f flag will run against this pull request / issue.
                // This URL should be same the URL of the pull request / issues in the GitHub event provided with the -e flag.
                // For instance, if you are using a GitHub event of a comment on the pull request X, the -u flag should be the URL of the pull request X.
                "-u=<GITHUB_URL>",
                // Absolute path to JSON file with GitHub event.
                // This GitHub event body defines the action that will run on the pull request / issue.
                // To get the GitHub event body, follow the instructions on https://github.com/reviewpad/reviewpad#how-to-get-the-github-event-body-internal-use-only
                "-e=<PATH_TO_GITHUB_EVENT_BODY>"
                // The GitHub event type
                // Determines how the events JSON file will be processed
                // To get the GitHub event body, follow the instructions on https://github.com/reviewpad/reviewpad#how-to-get-the-github-event-type-internal-use-only
                "-y=<GITHUB_EVENT_TYPE>"
            ],
            "env": {
                "INPUT_CODEHOST_SERVICE": "<CODEHOST_SERVICE_ENDPOINT>",
                "INPUT_SEMANTIC_SERVICE": "<SEMANTIC_SERVICE_ENDPOINT>",
                "INPUT_ROBIN_SERVICE": "<ROBIN_SERVICE_ENDPOINT>",
            },
            "program": "${workspaceFolder}/cli/main.go"
        }
    ]
}

How to get the GitHub event body (internal use only)

The -e flag is mandatory to run the debugger.

It represents the GitHub event that you wish to run the reviewpad.yml file against.

To extract a GitHub event, please follow the steps below:

  1. Navigate to the GitHub URL of the pull request you want to test against.
  2. Click on the reviewpad check under the Checks tab.
  3. From the DETAILS section of the check copy the Delivery ID.
  4. Go to the logs of the Entry Gate and filter out the logs using the query {$.delivery_id="[Delivery ID]" && $.msg="request received"}
  5. Copy the content inside the body field.
  6. Create a file under cli > debugdata with a name that ends with .json (e.g. my_event.json) and paste the content inside the file.
  7. This content is an escape JSON string. Use the JSON Parse & Stringify extension to parse the content by pressing Ctrl+Shift+P and searching for JSON: Parse Stringified JSON.
  8. Update the argument -e to point to the full path of the file you just created.

How to get the GitHub event type (internal use only)

The -y flag is mandatory to run the debugger.

It represents the type of GitHub event that you wish to run the reviewpad.yml file against.

To get the GitHub event type, please follow the steps below:

  1. Navigate to the GitHub URL of the pull request you want to test against.
  2. Click on the reviewpad check under the Checks tab.
  3. From the DETAILS section of the check copy the Event Type.
  4. Paste the content inside the -y flag.

If you wish to use the logs of the Entry Gate to the event type, please follow the steps below:

  1. Filter out the logs using the query {$.delivery_id="[Delivery ID]" && $.msg="request received"}
  2. Copy the content inside the headers.X-GitHub-Event field.
  3. Paste the content inside the -y flag.

Contributing

We welcome contributions to Reviewpad from the community!

See the Contributing Guide.

If you need any assistance, please join discord to reach the core contributors.

License

Reviewpad is available under the GNU Lesser General Public License v3.0 license.

See LICENSE for the full license text.

Compliance

reviewpad's People

Contributors

adrianoapmartins avatar denizzengin avatar dukex avatar ferreiratiago avatar fredoliveira avatar gildedhonour avatar jacekduszenko avatar krupalitrivedi avatar marcelosousa avatar michaelc0n avatar pkbhowmick avatar renovate[bot] avatar shay2025 avatar thedevsaddam avatar versoul avatar zolamk avatar zoldater avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

reviewpad's Issues

Add Builders to engine.Program

Is your feature request related to a problem? Please describe.
For consistency with the rest of the design, we should add builders to engine.Program and hide the struct elements.

Automatically add the author of the pull request as the assignee

Is your feature request related to a problem? Please describe.
Use case from early adopter: the ability to automatically add the author of the pull request as the assignee.

Describe the solution you'd like
We need a new action $assignAssignee() that receives a single string as the GH login and makes the right API call.

Update licences

Is your feature request related to a problem? Please describe.
Some files don't have the correct licences.

Describe the solution you'd like
We should update the licences in the needed files.

Describe alternatives you've considered
None

Additional context
None

Pull request templates

Is your feature request related to a problem? Please describe.
Right now, we don't have a pull request template.

Describe the solution you'd like
Create a pull request template.

Describe alternatives you've considered
None

Additional context
None

Groups and rules should be lists instead of maps

Is your feature request related to a problem? Please describe.
Since groups and rules can be defined based on other groups and rules, it doesn't make sense anymore for the properties "groups" and "rules" to be a map in the YML Reviewpad configuration.

Describe the solution you'd like
Turn "groups" and "rules" into lists so that the order of their execution matters.

Do not re-request review when reviewer has approved the review

Is your feature request related to a problem? Please describe.
Right now when a reviewer approves a review and reviewpad runs afterwards it re-requests a review.

Describe the solution you'd like
When a reviewer has approved the review, reviewpad shouldn't re-request a review from that reviewer.

Describe alternatives you've considered
none

Additional context
none

$startsWith built-in

Is your feature request related to a problem? Please describe.
To complement the $contains() built-in, it is useful to have a $startsWith() built-in.

Describe the solution you'd like

ย  startsWith


Description:

Determines whether a text starts with a certain sentence, returning true or false as appropriate.

Parameters:

variable type description
text string The text to search in
prefix string The prefix

Return value:

boolean

Returns true if prefix is a prefix of text, false otherwise.

Examples:

$startsWith("Testing string contains", "Test")     #true
$startsWith("Testing string contains", "string contains")      #false

A reviewpad.yml example:

rules:
  - name: isDevBranch
    kind: patch
    description: Verifies if the head branch of the pull requests starts with dev
    spec: $startsWith($head(), "dev/ ")

Use assert.FailNow in unit tests

Is your feature request related to a problem? Please describe.
At the moment, we are using log.Fatal to report failures in the unit tests.

Describe the solution you'd like
Use assert.FailNow.

CLI panic without optional flag 'event-payload string'

Describe the bug
new CLI flag described as optional

  -event-payload string (optional)
        File path to github action event in JSON format

but if i run CLI without this flag i got panic in file
cmd/cli/main.go L_52

because here ev.Name & ev.Payload are nil

func parseEvent(rawEvent string) (interface{}, error) {
	ev := &Event{}

	err := json.Unmarshal([]byte(rawEvent), ev)
	if err != nil {
		return nil, err
	}

	return github.ParseWebHook(*ev.Name, *ev.Payload)
}

To Reproduce
Run CLI without this optional flag

Expected behavior
No errors

Screenshots
CleanShot 2022-07-27 at 16 54 45@2x

CleanShot 2022-07-27 at 16 54 45@2x

Normalize Reviewpad.yml

Is your feature request related to a problem? Please describe.
Right now reviewpad configuration is done through reviewpad.yml file.

This configuration has optional properties. For instance, the property mode. This means that the value for the property mode can be filled (e.g. mode: silent) or not included in the configuration.

However, when no configuration is provided, reviewpad needs to assume a default behavior. In the case of mode the default behavior is silent.

We need to make sure that whenever an optional configuration is not provided, a default configuration is assumed.

Describe the solution you'd like
The idea is to create a normalize function able to normalize the reviewpad.yml configuration and make sure all optional parameters have a default value, i.e. normalize(reviewpad.yml): normalized_reviewpad.yml.

Describe alternatives you've considered
An alternative will be to have some read function that is able to safely read a property from reviewpad.yml. This function will require to either

  • (1) know the default values for each optional property, i.e. safely_read_property(reviewpad.yml, property): property_value or
  • (2) ask for a default value in case the property does not exists, i.e. safely_read_property(reviewpad.yml, property, default_value): property_value.

Additional context
We need to make sure where is the best place to perform this normalization. Either on reviewpad, action or host-event-handler.

Duplicated reviewpad report

Describe the bug
In this PR #101, it was generated 2 identical reviewpad reports.

To Reproduce
#101

Expected behavior
Only one reviewpad report should appear.

Screenshots
None

Improve 'unused rule' lint check

Is your feature request related to a problem? Please describe.
At the moment, the linter checks if a rule is not used in any workflow.

However, with the introduction of the '$rule()' built-in, it is possible for rules to be defined for the sole purpose of being used in the definition of other rules. Those rules don't show up in any workflow which makes the current lint check to fail.

Describe the solution you'd like
The linter needs to be improved to check if rules are not used in:

  1. Workflows and
  2. The definition of other rules

Describe alternatives you've considered
Simply remove this lint check. This is not desirable as we want to reduce the amount of noise in the reviewpad configuration.

Additional context
This is an issue since v1.1.0.

Paginate list collaborators request in `$assignRandomReviewer` action builtin

Is your feature request related to a problem? Please describe.
The $assignRandomReviewerfunction builtin does a request to list the pull request collaborators which isn't paginated.

Describe the solution you'd like
We should improve this request by paginating it. Look at getPullRequestFiles which does a paginated request to list the pull request files.

Describe alternatives you've considered
None.

Additional context
None.

Test Eval function in engine exec

Is your feature request related to a problem? Please describe.
To conclude a first phase of adding tests, we need to add unit tests for the Eval function.

Remove unnecessary pull request request

Is your feature request related to a problem? Please describe.
Currently, in the $assignRandomReviewer action builtin, we perform a pull request request just to get the requested reviewers when GitHub API provides a specific request for this.

Describe the solution you'd like
Instead of using a generic request (pull request request) just to get the pull request requested reviews, use https://docs.github.com/pt/rest/pulls/review-requests#list-requested-reviewers-for-a-pull-request

Describe alternatives you've considered
None

Additional context
None

Cache the evaluation of rules

Is your feature request related to a problem? Please describe.
The built-in $rule() allows us to evaluate on the spot the rule passed as argument. This is different than the $group() built-in which simply retrieves the already computed result of the group.

Describe the solution you'd like
Replicate the same behaviour of $group() to $rule().

Use label key in $addLabel and $removeLabel built-in

Is your feature request related to a problem? Please describe.
Consider the following specification:

labels:
  major-release:
    name: 'release:major :arrow_up::hash::hash:'
    description: 'Release the changes as a major'
    color: 'BC304A'

rules:
  - name: is-major-release
    kind: patch
    description: Is major release
    spec: '$startsWith($head(), "major/")'

workflows:
  - name: enforce-branch-naming
     description: Enforce branch naming
     always-run: true
     if:
       - rule: head-branch-is-major
         extra-actions:
           - '$addLabel("major-release")'

Here in the action addLabel, instead of adding the GH label "major-release" we would like to add the name associated with this label in the labels map. This is much nicer than to specify: $addLabel("release:major :arrow_up::hash::hash:")

Describe the solution you'd like
We should first check in the action if the argument is a key in the labels and if so, retrieve the name associated with it. If no one name is associated with it, we simply use the argument as the name of the label.

Describe alternatives you've considered
None.

Additional context
Related to #39

Improve aladino MockDefaultEnv

Is your feature request related to a problem? Please describe.
Right now, we have MockDefaultEnv + MockDefaultEnvWithBuiltIns + MockDefaultEnvWithEvent which are MockDefaultEnv with extra parameters.

Describe the solution you'd like
We should update MockDefaultEnv so that we remove MockDefaultEnvWithBuiltIns and MockDefaultEnvWithEvent.

Describe alternatives you've considered
None

Additional context
None

Assign team reviewer

Is your feature request related to a problem? Please describe.
Currently, we can't assign a team to review.

Describe the solution you'd like
Develop a builtin $assignTeamReviewer() that given a team slug, assigns the team to review the pull request.

Describe alternatives you've considered
None.

Additional context
None.

built-in: length

Is your feature request related to a problem? Please describe.
For certain workflows, we need to get the length of a particular array.

For example, we need to support the following rule:

  - name: has-at-least-one-reviewer
    kind: patch
    description: Has more than one reviewer
    spec: '$length($reviewers) > 1'

Describe the solution you'd like
To support the above use case, we need to a new built-in utility function $length.

Documentation at: https://github.com/reviewpad/docs/pull/11

New labels are not being created

Describe the bug
New labels added to reviewpad.yml are not being created on github repository.

To Reproduce

  1. Add a label into reviewpad.yml that does not exists on the github repository.
  2. Run reviewpad action.
  3. The reviewpad action will fail with a 404 from github because the label does not exits.

Expected behavior
When the label does not exist on github repository it should be created.

Screenshots
none

Support multiline values

Is your feature request related to a problem? Please describe.
Right now our parser is not able to build the AST of a multiline values.

Here's an example:

workflows:
  - name: my-policy
    if:
      - rule: tautology
    then:
      - > 
        $warn("Required rules: 
        - rule 1
        - rule 2")

Describe the solution you'd like
Update parser in order to be able to handle multiline values.

Describe alternatives you've considered
none

Additional context
With multiline parse fails with error.

syntax error on 
2022/07/07 17:13:49 parse error: failed to build AST on input  $warn("Required rules:  - rule 1  - rule 2")

Retrieve base and head repository information

Is your feature request related to a problem? Please describe.
Some built-ins require information from the base and the head branch. What happens is that in the case of forks, we might need to retrieve the base and head repositories information. At the moment, we simply retrieve the base through https://github.com/reviewpad/reviewpad/blob/main/utils/github.go#L19.

Describe the solution you'd like
We need functions to retrieve owner and repository both from the base and head repositories.

Disable line directives in goyacc generated files

Is your feature request related to a problem? Please describe.
Currently whenever we perform task build, the goyacc generated files (parser.y) have line directives.
These line directives sometimes are incoerent with other operative systems.

Describe the solution you'd like
Disable line directives in goyacc generated files.
Currently our Taskfile.yml which contains the build commands has the goyacc -o lang/aladino/parser.go -p Aladino lang/aladino/parser.y command.
I propose we add the -l argument to this command so the line directives are disabled, resulting in the command:
goyacc -l -o lang/aladino/parser.go -p Aladino lang/aladino/parser.y

Describe alternatives you've considered
None

Additional context
None

Allow custom configuration of built-in actions

Allowing customisation of built-ins actions is useful.

Here's a use case where we want to prevent reviewer assignment for pull requests that are in draft.

Three possible solutions:

api-version: reviewpad.com/v3.x

# edition can be team (open-source built-ins) or professional (all available built-ins)
edition: professional

# mode can be either silent (no explanation) or verbose
mode: verbose

# rules specify conditions on pull requests
rules:
  - name: is-draft
    spec: '$isDraft()'

# SOLUTION 1: As a configuration
# configuration of actions
# by default, all actions are enabled
# in this section, we configure when a particular action is disabled
configuration:
  - name: disable-reviewer-assignment
    # if actions had kinds, we could simply put kinds here
    on-actions:
      - '$assignReviewer'
      - '$assignRandomReviewer'
    disabled-if:
      - rule: is-draft

# SOLUTION 2: As a built-in
# workflows specifies a list of workflows; it is a list because the order of 
# execution matters.
workflows:
  - name: reviewer-assignment
    always-run: true
    if:
      - rule: is-draft
    then:
      - '$disableReviewerAssignment()'

# SOLUTION 3: As a general built-in
# workflows specifies a list of workflows; it is a list because the order of 
# execution matters.
workflows:
  - name: reviewer-assignment
    always-run: true
    if:
      - rule: is-draft
    then:
      - '$disableActions(["..."])'

Fetch last update date from push for $isWaitingForReview

Is your feature request related to a problem? Please describe.
Right now the builtin $isWaitingForReview requires the value of the last update date in order to understand if a pull request is waiting for review or not.

This value is being fetched from list of the pull request commits, mainly from the last commit. This is because the list of commits is in chronological order.

However, it is possible for a user to set a commit date manually, which means that we can't trust the commit date.

Describe the solution you'd like
The proposed solution is to look for the date of the last pull request push.

Describe alternatives you've considered
none

Additional context
Fetching the last push it means to fetch all push request timeline events and filter all events in order to get the last push.

The timeline fetch is only possible through github graphql api.

Add a CLA to the project

Is your feature request related to a problem? Please describe.
We're humbled by the contributions from the community in such a short time. We should check if we need to add a CLA similarly to what other open source projects do so that we can officially accept their contributions.

Describe the solution you'd like
This requires further investigation. Check for example go-github.

$fail() action

Is your feature request related to a problem? Please describe.
At the moment, we have added a ignore-errors flags to the Reviewpad configuration.

However, in certain cases, it might be highly beneficial for the user to specify that the action should actually fail.

For example:

workflows:
  - name: fail-on-certain-pull-requests
    description: Certain pull requests should be blocked by Reviewpad to prevent merges
    if: 
      - rule: pull-request-is-blocked
    then:
      - '$fail()'

Describe the solution you'd like
A new built-in action $fail() that simply returns an error so that the Reviewpad action is red.

$fail should wait for report to be generated before failing the action

Is your feature request related to a problem? Please describe.
Right now, the report is only generated when all the program is executed.
When the $fail action is part of the program, the report doesn't get to be generated because upon the execution of the built-in the GitHub action fails altogether and the report doesn't get to be generated.

Describe the solution you'd like
Perform the execution with the following order:

  1. Generate the report
  2. Execute the $fail action.

Describe alternatives you've considered
None

Additional context
None

Dry-run shouldn't create labels

Describe the bug
The idea of dry-run is to be able to run reviewpad without ever changing the pull request or the repository. Although this is true for the executing of rules, the same is not valid for labels.

When is comes to labels, reviewpad does a GitHub request for getting all labels and creating those that do not exist. This shouldn't happen when on dry-run.

To Reproduce
Run reviewpad on dry-run with a reviewpad.yml that creates a new label. You will see that the label is created in the repository.

Expected behavior
The label shouldn't be created when running on dry-run.

Screenshots
none

Re-request review when reviewer has approved the review

Describe the bug
When a reviewer approves a pull request, their review is being re-requested when reviewpad re-runs.

To Reproduce
See #192.

Expected behavior
When a reviewer has approved the review, reviewpad shouldn't re-request a review from that reviewer.

Screenshots
None

Unhandled error at runner.go

At runner.go there's:

    //........
evalEnv.Collector.Collect("Completed Analysis", map[string]interface{}{
	"pullRequestUrl": evalEnv.PullRequest.URL,
})

return program, nil

However, the Collect can return an error:

type Collector interface {
	Collect(eventName string, properties map[string]interface{}) error
}

Therefore, there's an unhandled error for evalEnv.Collector.Collect(...) call

Improve `$assignReviewer` action builtin

Is your feature request related to a problem? Please describe.
Right now, we are performing a set of checks to the args given in $assignReviewer action builtin that are already performed in type checks.
Besides this, it is needed to check if at least 1 user is provided in the given list of users which a review can be requested and also check if the given number of required reviewers is 0.

Describe the solution you'd like
Remove and add the necessary checks and react to them.

Describe alternatives you've considered
None

Additional context
None

Remove mocks files from code coverage

Is your feature request related to a problem? Please describe.
The mock files are currently being counted by go coverage tool and thus reduces the code coverage percentage for the packages where they are consumed.

Describe the solution you'd like
Currently, we ignore the generated parser.go file from the code coverage by specifying the file path in exclude-from-code-coverage.txt which is consumed by a script (exclude-from-code-coverage.sh) that excludes this file from the code coverage.
We should add the file paths of the mocks files to this exclude-from-code-coverage.txt.

Describe alternatives you've considered
None

Additional context
None

Support string interpolation

Is your feature request related to a problem? Please describe.
Currently, we don't support string interpolation in Aladino and we may want to be able to do something like $infof("Welcome %v", $author()).

Describe the solution you'd like
I propose we create a new built-in called sprintf which receives two argumens:

  • format: this argument is of type string and represents the string containing custom specifiers that the sprintf uses to format the final output string.
  • a ...interface{}: this argument refers to the list of a variable number of arguments that need to be formatted and printed.
    And returns the formatted string.

So in Aladino terms, the built-in would have the type: aladino.FunctionType([]aladino.Type{aladino.StringType()}, aladino.BuildArrayOfType(aladino.BuildStringType())).

Example of usage:
$info(sprintf("Welcome %v", [$author()]))

Describe alternatives you've considered
None

Additional context
None

Add a name property to labels

Is your feature request related to a problem? Please describe.
In some cases it is useful to provide a name of a label that is not a YAML key, e.g. "release:major".

Describe the solution you'd like
As part of the v2.x series we should add a new property name to the labels.

Describe alternatives you've considered
None.

Additional context
None.

Allow a comment only once in a pull request

Is your feature request related to a problem? Please describe.
Right now, it exists a $comment() action that can be executed if a rule is followed.
However, this rule can be always followed whenever the workflow is triggered.
This can cause the same comment to be made several times in the same pull request which can be annoying at certain cases.

Describe the solution you'd like
Develop an action that makes a comment only once in a pull request.

Describe alternatives you've considered
None.

Additional context
None.

feat: $addToProject built-in

Is your feature request related to a problem? Please describe.
One use case that we have is that we want to automatically add a pull request to a given project when the pull request doesn't have an associated issue.

We would like to support the following configuration:

api-version: reviewpad.com/v3.x

mode: silent
edition: professional

rules:
  - name: does-not-have-issues
    kind: patch
    description: has associated issue
    spec: '!$hasLinkedIssues()'

 - name: add-to-project
    description: Add to project pull requests without linked issues
    if:
      - rule: does-not-have-issues
    then:
      - '$addToProject("Reviewpad")'

Describe the solution you'd like
A new built-in function $addToProject(...).

At this stage, it's unclear how we can identify the project is a user friendly way.

Reviewer assignment only after pull request is ready for review

Is your feature request related to a problem? Please describe.
It is annoying to get review requests for pull requests that are marked still in draft.

Describe the solution you'd like
Allow a specification in Reviewpad where we can ensure that the reviewer assignment is triggered once the pull request is ready for review.

YAML property to define failure mode

Is your feature request related to a problem? Please describe.
Although the engine runners return an error, this error is at the moment ignored by the runner users such as the Reviewpad Action. It should be up to the user to specify if that is the intended behaviour.

Describe the solution you'd like
Introduce a new boolean property in the YAML called "fail-on-error" which is true by default.

Describe alternatives you've considered
None.

Additional context
None.

Improve log for non existing label warning

Is your feature request related to a problem? Please describe.
When we try to add a label, with the $addLabel built-in, if that label doesn't exist we create the label and log an warning saying [warn]: addLabel LABEL_NOT_FOUND was not found in the environment. This format isn't very friendly.

Describe the solution you'd like
Change the log warning to [warn]: LABEL_NOT_FOUND was not found in the environment.

Describe alternatives you've considered
None

Additional context
None

Distribute review workload between developers

Is your feature request related to a problem? Please describe.
Right now whenever a reviewer assignment is performed reviewpad has no intelligence to it, meaning that on a group of X people it can happen that the reviewers are unevenly distributed.

For instance, on the following reviewpad.yml configuration it can happen that marcelo gets 80% of the code reviews and tiago gets the remaining 20%.

api-version: reviewpad.com/v3.x

groups:
  - name: owners
    description: Group of owners
    kind: developers
    spec: '["marcelosousa", "ferreiratiago"]'

rules:
  - name: tautology
    kind: patch
    description: always true
    spec: 'true'

workflows:
  - name: always-assign-reviewer
    description: Add label with size of the pull request
    always-run: true
    if:
      - rule: tautology
        extra-actions:
          - $assignReviewer($group("owners"), 1)

Reviewpad should be able to be a bit smart about reviewer assignment to pull requests.

Describe the solution you'd like
A possible solution could be to fetch all reviewers from all open pull requests from github and order the reviewers from the least busy.

The calculation of busy should be smart and count not only the total amount of pull requests but also the total amount of files (or even the total amount of lines) - an efficient and good strategy should be proposed here.

Maybe even look at the user's github status in order to understand if the user has any busy or vacation status.

Describe alternatives you've considered
none

Additional context
Please also take into consideration the following built-ins:

Turn labels into a list

Is your feature request related to a problem? Please describe.
In #38 we have added a new field "name" into the label. In the v3.x as it will 'breaking' from v2.x we should take the opportunity to convert the map into a list of labels.

Describe the solution you'd like
Turn a map into a list.

Describe alternatives you've considered
None.

Additional context
None.

built-in: reviewerStatus

Is your feature request related to a problem? Please describe.
To support code review policies where we want a first approval from user X and then a second approval from user Y, we need to retrieve the reviewer status.

As an example of a rule,

  - name: approved-by-marcelosousa
    kind: patch
    description: Checks if the pull request was approved by marcelosousa
    spec: '$reviewerStatus("marcelosousa") == "approved"'

Describe the solution you'd like
To support the above use case, we need to a new built-in utility function $reviewerStatus.

Documentation at: https://github.com/reviewpad/docs/pull/12

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.