Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cli)!: refactor factory/CLI to be more testable #725

Merged
merged 9 commits into from Feb 3, 2021
Merged

Conversation

bcoe
Copy link
Contributor

@bcoe bcoe commented Jan 29, 2021

Taking inspiration from @jbottigliero's work on #581, this PR refactors our factory class, and the CLI entry-point to be more easily tested/shared:

  • there's now a factory.runCommand helper that can be used as an entry-point to GitHub releases or Release PRs.
  • bin/release-please.ts does not execute unless it's being run by node, allowing it to be tested in isolation.
  • I refactored how the factory exports its helpers, making it easier to mock with sinon.

future work:

  • we should flesh out unit tests for the CLI further:
    • adding test cases for loading config.
    • adding a test case that resembles how config will be passed in by the GitHub action.
  • I did not pull over the improved conventional changelog section types that @jbottigliero wrote (perhaps you could submit a patch?).
  • I have not added support for config files yet (@joeldodge79 given you use a GitHub action, you might want to think through how the config is actually loaded, since yargs assumes a file system. You will likely want to have something that reaches out using the GitHub API and pulls in config).

feat: packageName parameter is now optional
refactor!: helpers in factory class renamed.
refactor!: more options pulled to top level (some types changed in process)
refactor!: GitHub release now uses "run" rather than "createRelease" to execute
refactor!: drop unused proxy-key parameter.

CC: @joeldodge79

@bcoe bcoe requested a review from a team as a code owner January 29, 2021 22:44
@google-cla google-cla bot added the cla: yes This human has signed the Contributor License Agreement. label Jan 29, 2021
@codecov
Copy link

codecov bot commented Jan 29, 2021

Codecov Report

Merging #725 (dd12f3b) into master (21ec33c) will increase coverage by 0.38%.
The diff coverage is 81.09%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #725      +/-   ##
==========================================
+ Coverage   86.72%   87.11%   +0.38%     
==========================================
  Files          56       58       +2     
  Lines        7089     7288     +199     
  Branches      662      659       -3     
==========================================
+ Hits         6148     6349     +201     
+ Misses        940      938       -2     
  Partials        1        1              
Impacted Files Coverage Δ
src/github.ts 82.52% <36.58%> (+1.21%) ⬆️
src/bin/release-please.ts 88.38% <85.71%> (ø)
src/factory.ts 91.78% <91.78%> (ø)
src/github-release.ts 96.66% <94.11%> (-0.62%) ⬇️
src/index.ts 100.00% <100.00%> (ø)
src/release-pr.ts 93.10% <100.00%> (-0.34%) ⬇️
src/releasers/index.ts 100.00% <0.00%> (+12.06%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 21ec33c...197d8e5. Read the comment docs.

Copy link
Collaborator

@joeldodge79 joeldodge79 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice improvements! some questions and a couple nits

regarding the aggregate packages config: I'd rather stay within the bounds of yargs for cli and action inputs defined in the workflow for the GH-action side:

  • cli: --packages flag for the cli: json encoded string (or array of json strings)
    • consider adding yargs.config() to make cli users' lives easier supporting actual nested json in the json config file rather than requiring embedded json encoded strings in the json config file)
    • cli users may happen to choose to store their CLI config somewhere in their repo but that doesn't affect us
  • action: packages input key: array of objects defined directly in the workflow file

src/bin/release-please.ts Show resolved Hide resolved
src/bin/release-please.ts Show resolved Hide resolved
src/index.ts Show resolved Hide resolved
src/release-pr.ts Outdated Show resolved Hide resolved
src/bin/release-please.ts Outdated Show resolved Hide resolved
test/cli.ts Outdated Show resolved Hide resolved
Comment on lines +66 to +72
export const factory = {
githubRelease,
releasePR,
releasePRClass,
run,
runCommand,
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this common factory. nifty how you collected them together like this for a single entry point.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's maybe note the most "TypeScripty" looking code, but it's an approach I learned from working on Node:

https://github.com/nodejs/node/blob/master/lib/fs.js#L2058

I've found it makes it really easy to mock the methods, vs., static methods.

Copy link

@jbottigliero jbottigliero left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me!

In comparison to #581, one of the things that it looks like the google-github-actions/release-please-action (and other potential Node API users) will still have to handle is the empty command flow (calling both the github-release and release-pr in succession). I saw this logic being shared as way to create a single source of truth for release-please behaviors, especially with the idea of introducing new triggers (ie. the Google Cloud Build example). It seems like that could maybe still be done in a follow-up patch in addition to the shared changelog options parsing?

Copy link
Collaborator

@joeldodge79 joeldodge79 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (up to you if you want to incorporate my suggestion or not, I don't feel strongly either way)

src/release-pr.ts Show resolved Hide resolved
@bcoe
Copy link
Contributor Author

bcoe commented Feb 1, 2021

I saw this logic being shared as way to create a single source of truth for release-please behaviors, especially with the idea of introducing new triggers (ie. the Google Cloud Build example). It seems like that could maybe still be done in a follow-up patch in addition to the shared changelog options parsing?

@jbottigliero if it's okay with you, let's think about this in a follow up. One slight concern I have, is that creating a GitHub Release, vs., creating a Release PR, take enough divergent config options, that we might still want to do some validation in the CLI and action before calling a factory?

bcoe and others added 6 commits February 3, 2021 11:07
refactor!: helpers in factory class renamed.
refactor!: more options pulled to top level (some types changed in process)
refactor!: GitHub release now uses "run" rather than "createRelease" to execute
Co-authored-by: Joel Dodge <joeldodge@google.com>
Copy link
Contributor

@chingor13 chingor13 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few comments/questions.

Also, can you write in the release notes what needs to be renamed? The GitHub app will need to make some code changes and it would be nice if the notes explicitly state X is renamed to factory.Y.

src/factory.ts Outdated
} from './github-release';
import {getReleasers} from './releasers';

export function runCommand(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need these extra exports if they are included into the single factory export?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this extra factory necessary? The only place this is called is in the argv parsing and at that point you already know which command you're trying to execute.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking it might be nice in the action, but maybe it's overkill.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chingor13 actually, one reason I would like to keep this approach, was that it made it really nice to test the CLI:

      let classToRun: GitHubRelease;
      // This logic is used to capture the class that would
      // be executed, allowing us to validate that the appropriate
      // properties were assigned from the argument parser:
      sandbox.replace(
        factory,
        'run',
        (runnable): Promise<undefined> => {
          classToRun = runnable as GitHubRelease;
          return Promise.resolve(undefined);
        }
      );
      parser.parse(
        'github-release --repo-url=googleapis/release-please-cli --package-name=cli-package'
      );

Because I was able to mock just the logic that runs the GitHub Release or Release PR, without actually running it.

src/index.ts Show resolved Hide resolved
@bcoe bcoe requested a review from chingor13 February 3, 2021 22:06
@bcoe bcoe merged commit 713bfc5 into master Feb 3, 2021
@bcoe bcoe deleted the better-config branch February 3, 2021 22:33
@release-please release-please bot mentioned this pull request Feb 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes This human has signed the Contributor License Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants