Skip to content

Commit

Permalink
Merge branch 'next' of github.com:HubSpot/hubspot-cli into jy/integra…
Browse files Browse the repository at this point in the history
…te-new-http-error-object
  • Loading branch information
joe-yeager committed Jul 25, 2024
2 parents 2b7d555 + 16290cf commit a9ca1fc
Show file tree
Hide file tree
Showing 39 changed files with 844 additions and 780 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
4 changes: 0 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,4 @@ jobs:
yarn test-cli
env:
PORTAL_ID: ${{ secrets.ACCEPTANCE_TEST_PORTAL_ID }}
CLI_PATH: ${{ secrets.ACCEPTANCE_TEST_CLI_PATH }}
PERSONAL_ACCESS_KEY: ${{ secrets.ACCEPTANCE_TEST_PERSONAL_ACCESS_KEY }}
CLIENT_ID: ${{ secrets.ACCEPTANCE_TEST_CLIENT_ID }}
CLIENT_SECRET: ${{ secrets.ACCEPTANCE_TEST_CLIENT_SECRET }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ context
coverage
hubspot.config.yml
hubspot.config.yaml
acceptance-test.config.yml
hs-acceptance-test.config.yml
lerna-debug.log
npm-debug.log
npm-debug.log.*
Expand Down
46 changes: 38 additions & 8 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,40 @@ yarn test-cli
yarn check-deps # Should output "No dependency issues found"
```

### Testing with Docker
We use [Rancher Desktop](https://rancherdesktop.io/) to work with Docker containers. Install via the links on their homepage or with homebrew by running `brew install --cask rancher`.

When launching Rancher Desktop for the first time, you will need to:
- DISABLE the `kubernetes` checkbox
- Select `dockerd` as the container runtime
- Select `Manual` for configure path

Then, you will need to manually add this line to your shell's configuration file (i.e. `~/.bash_profile` or `~/.zshrc`):
```bash
export PATH=${PATH}:~/.rd/bin
```

Then you should have access to the `docker` CLI command (as long as Rancher Desktop is running).

To execute the CLI tests in a docker container, run:
```bash
yarn test-docker
```

This will do several things:
1. It will generate a new hs-cli-image docker image, copy project files into it, and install dependencies
2. It will then run a container and execute our test scripts inside of it
3. The container will remove itself after the run completes

It is also possible to open an interactive linux shell. This lets you manually run the CLI tests and commands:
```bash
yarn build-docker && docker container run -it --rm --name=hs-cli-container hs-cli-image bash
```
**TIP:** Type `exit` to quit

## Merging
To merge, either create, or have a maintainer create a blank branch, and set your PRs base branch to the blank branch. Merge your PR into the blank branch, and ensure that it passes the build. Then merge the new branch into main.


## Documentation

- [Technical Design](./docs/TechnicalDesign.md)
Expand All @@ -85,18 +115,18 @@ alias view-installed-links="( ls -l node_modules ; ls -l node_modules/@* ) | gre
alias view-yarn-links="tree ~/.config/yarn/link"
```

`view-installed-links` will show symbolic links in the `node_modules` directory of the cwd. So if you ran `yarn link package-name`,
`view-installed-links` will show symbolic links in the `node_modules` directory of the cwd. So if you ran `yarn link package-name`,
you can use this to make certain the linking process was successful.

`view-yarn-links` will show the packages that have links setup in `yarn`. So if you ran `yarn link` in `package-name` you
can use this to make certain it is set up and pointing to the correct directory. This relies on the `tree` command being installed.
`view-yarn-links` will show the packages that have links setup in `yarn`. So if you ran `yarn link` in `package-name` you
can use this to make certain it is set up and pointing to the correct directory. This relies on the `tree` command being installed.

If you don't have `tree` available an alternate command is `alias view-yarn-links="ls -R -l ~/.config/yarn/link"`

### Using the node debugger
If you find yourself in a situation where you would like to step through the code in this project line by line in the debugger,
you can edit `packages/cli/bin/hs` and add either `--inspect` or `--inspect-brk` to the end of the hashbang like so:
`#!/usr/bin/env node {all the other arguments} --inspect`. The two function similarly, with the main difference being that `--inspect-brk`
you can edit `packages/cli/bin/hs` and add either `--inspect` or `--inspect-brk` to the end of the hashbang like so:
`#!/usr/bin/env node {all the other arguments} --inspect`. The two function similarly, with the main difference being that `--inspect-brk`
waits for the debugger to attach before beginning execution.

Once that is done, you should see something like this:
Expand All @@ -109,5 +139,5 @@ Debugger listening on ws://127.0.0.1:9229/6ac9241f-419c-495e-9b5e-310391f7b36c
For help, see: https://nodejs.org/en/docs/inspector
```

You can then open your [inspector of choice](https://nodejs.org/en/learn/getting-started/debugging#inspector-clients) and
walk through the code
You can then open your [inspector of choice](https://nodejs.org/en/learn/getting-started/debugging#inspector-clients) and
walk through the code
11 changes: 11 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Create image based on the official Node image from dockerhub
FROM node:16

# Create base directory
WORKDIR /usr/src/hubspot-cli

# Get all the code needed to run the app locally
COPY . .

# Install dependencies
RUN yarn
8 changes: 0 additions & 8 deletions acceptance-tests/CHANGELOG.md

This file was deleted.

58 changes: 23 additions & 35 deletions acceptance-tests/README.md
Original file line number Diff line number Diff line change
@@ -1,87 +1,75 @@
# HubSpot CLI Acceptance Tests

This project tests `hs.*` commands as if they were being used by an end-user.
This project tests our CLI's `hs <*>` commands as if they were being used by an end-user.

## Getting Started

The main test execution is kicked off by running `yarn test-cli` from the root of `hubspot-cli`. This will run the `run-tests` scipe which itself is a CLI, so to see the available options, you can `run-tests --help`. This was done so that the tests can be installed against any given version of the CLI and tested against it. In addition, it was done to keep the test logic separated from the CLI library.
The main test execution is kicked off by running `yarn test-cli` from the root of `hubspot-cli`. This will run the `run-tests` script which itself is a CLI, so to see the available options, you can `run-tests --help`. This was done so that the tests can be installed against any given version of the CLI and tested against it. In addition, it was done to keep the test logic separated from the CLI library.

Note that if you are testing against a QA portal, not a PROD one, you'll need to add the `--qa` flag when running the script. There is still an outstanding issue with this because we attempt to add the `--qa` flag to all `hs` commands, however it is not available for all commands.

### Setup

To setup these tests, first [create an app](https://developers.hubspot.com/docs/api/creating-an-app) in a [HubSpot developer account](https://app.hubspot.com/signup-hubspot/crm). Under the "Auth" tab, give your app at least one scope, and set the redirect URL to `localhost:3000/oauth-callback`, and save your changes. Also, take note of your Client ID, and Client Secret and click "Copy full URL". ![image](https://user-images.githubusercontent.com/48874841/175648758-b2fdb491-90f8-4573-ad9e-af7e1236548c.png)
To setup these tests, there are two required arguments and one optional one:

Next, in the navigation bar, click "Testing", and then "Create app test account". Then, paste the OAuth URL you copied earlier into your browser, choose your newly created test account, and click "Connect App".

Now, navigate back to the "Testing" page, and click your test account. Take note of the Account ID in the URL (`https://app.hubspot.com/dashboard-library/ACCOUNT_ID`). Then [navigate to the following page and generate a personal access key](https://app.hubspot.com/portal-recommend/l?slug=personal-access-key) that is associated with your test account.

Generate [a github token](https://github.com/settings/tokens/new) to test with.

You know have all the information required to create a `.env` file in the [Configuration](./README.md#configuration) section.

Finally, you must add an asset to your new test account. To do this, navigate to the [HubSpot marketplace](https://ecosystem.hubspot.com/marketplace/website/free-cms-accelerator-themes), log into your test account, and install an asset.
1. The ID of a HubSpot account that you are a user in
2. Your generated personal access key in that account (available in [personal access key ui](https://app.hubspot.com/l/personal-access-key))
3. [Optional] A path to an instance of the CLI. The test runner will execute the commands against this provided instance
- The default behavior is to use `../packages/cli/bin/hs`

### Configuration

There are four ways to pass in necessary configuration to the script.
There are three ways to pass in necessary configuration to the script.

1. Creating a `.env` file in `acceptance-tests` folder. Note that each variable must be on a new line - you may need to bypass the formatter of your IDE for this.
1. Creating a `.env` file in `acceptance-tests` folder.

```bash
ACCOUNT_ID="9289088"
CLI_PATH="hs"
ACCOUNT_ID="123456789"
PERSONAL_ACCESS_KEY="AiRiNGU2Y***************m1wLi2s8k2UlMYHEX"
GITHUB_TOKEN="123a4b56-****-****-****-************"
CLI_PATH="hs"
```

2. Through environment variables.

```bash

export ACCOUNT_ID="9289088"
export CLI_PATH="hs"
export ACCOUNT_ID="123456789"
export PERSONAL_ACCESS_KEY="AiRiNGU2Y***************m1wLi2s8k2UlMYHEX"
export GITHUB_TOKEN="123a4b56-****-****-****-************"
export CLI_PATH="hs"
```

3. Through arguments on the `run-tests` script

```bash
run-tests --accountId=9289088 --cliPath=hs --personalAccessKey="*********" --githubToken="********"
yarn run-tests --accountId=123456789 --personalAccessKey="*********" --cliPath=hs
```

4. If you need to override any environment variables at a test variable, you can do that via the `setLocalTestOverrides` function available in `env.js`
Alternatively, we support the following aliases:

The priority is Local Test Overrides > CLI Arg Overrides > Environment Variables
```bash
yarn run-tests --a=123456789 --pak="*********" --c=hs
```

### Running Locally

1. Run `lerna bootstrap` to install dependencies
2. Run `yarn test-cli`
2. Run `yarn test-cli` from the root of the CLI repo

**NOTE:** Include the `--debug` flag for more verbose output

## Why Jasmine

You may be wondering why we are using Jasmine, and not Jest. The reason is because Jest does not provide an API for executing the tests within code. We need to do this since we are wrapping the tests within a CLI.

## Accounts

A couple of account have been set up specifically for testing. They are QA Account 105786502 and Prod Account 9289088. If you add any test data to the accounts for testing, ensure you add it to the above two.
A couple of accounts have been set up specifically for testing. They are QA Account 105786502 and Prod Account 9289088. If you add any test data to the accounts for testing, ensure you add it to the above two.

## Issues

The `.env` file does not get recognized when running [act](https://github.com/nektos/act) locally to run the tests within the github action. To bypass this, you can comment out the `.env` line in the `.gitignore` file and run `act again`. See https://github.com/nektos/act/issues/193 for more info.

## To Do

- Only add `--qa` flag when needed to `hs` commands

- Bulk out test coverage

- Sometimes the initial bootstrapping said the auth token is no longer valid, not too sure why this is. Investigate

## Gotchas

- Currently sometimes the personal-access-key test is flakey. Run the tests again and it should pass.
- Currently the personal-access-key test is flakey. Run the tests again and it should pass.

- The tests seem to trip up on usages of the `ora` library. To get around this, we have a list of blacklisted strings. If your test is being picky about ora, add the error message to the blacklist in `cmd.js`
6 changes: 4 additions & 2 deletions acceptance-tests/lib/constants.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const CONFIG_FILE_PATH = 'acceptance-test.config.yml';
const CONFIG_FILE_NAME = 'hs-acceptance-test.config.yml';
const DEFAULT_CLI_PATH = '../packages/cli/bin/hs';

module.exports = {
CONFIG_FILE_PATH,
CONFIG_FILE_NAME,
DEFAULT_CLI_PATH,
};
66 changes: 32 additions & 34 deletions acceptance-tests/lib/env.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
const path = require('path');
const dotEnv = require('dotenv');
const { existsSync } = require('fs');
const { DEFAULT_CLI_PATH } = require('./constants');

let dotEnvConfig;

(() => {
Expand All @@ -19,8 +22,7 @@ const getTruthyValuesOnly = obj => {
return truthyValuesObj;
};

let localOverrides = {};
let localTestOverrides = {};
let argsOverrides = {};

const getEnvValue = envVariable => {
return (
Expand All @@ -29,62 +31,58 @@ const getEnvValue = envVariable => {
);
};

const setLocalTestOverrides = (overrides = {}) => {
localOverrides = { localOverrides, ...overrides };
};

const setArgsOverrides = args => {
args.portalId && (localOverrides.portalId = args.portalId);
args.cliPath && (localOverrides.cliPath = args.cliPath);
args.portalId && (argsOverrides.portalId = args.portalId);
args.cliPath && (argsOverrides.cliPath = args.cliPath);
args.personalAccessKey &&
(localOverrides.personalAccessKey = args.personalAccessKey);
args.githubToken && (localOverrides.githubToken = args.githubToken);
localOverrides.qa = args.qa;
localOverrides.debug = args.debug;
localOverrides.headless = !!args.headless;
(argsOverrides.personalAccessKey = args.personalAccessKey);
argsOverrides.qa = args.qa;
argsOverrides.debug = args.debug;
argsOverrides.headless = !!args.headless;
};

const envOverrides = getTruthyValuesOnly({
portalId: getEnvValue('PORTAL_ID') || getEnvValue('ACCOUNT_ID'),
cliPath: getEnvValue('CLI_PATH'),
personalAccessKey: getEnvValue('PERSONAL_ACCESS_KEY'),
githubToken: getEnvValue('GITHUB_TOKEN'),
});

const getTestConfig = () => {
// Test-specific Overrides > Command-line Args > Env vars
const config = Object.assign(
{},
envOverrides,
localOverrides,
localTestOverrides
);
// Command-line Args > Env vars
const config = Object.assign({}, envOverrides, argsOverrides);

if (!config.portalId)
if (!config.portalId) {
throw new Error(
'accountId must be defined. Either set the ACCOUNT_ID environment variable, or use the --accountId flag to pass it in.'
'accountId must be defined. Either set the ACCOUNT_ID environment variable or use the --accountId flag to pass it in.'
);
}

if (!config.cliPath)
throw new Error(
'cliPath must be defined. Either set the CLI_PATH environment variable or use the --cliPath flag to pass it in.'
);
if (!config.cliPath) {
const defaultPath = path.join(process.cwd(), DEFAULT_CLI_PATH);

if (!config.personalAccessKey)
throw new Error(
'No valid auth for personalAccessKey was found. Set the PERSONAL_ACCESS_KEY environment variable or use the --personalAccessKey flag to pass it in.'
);
if (existsSync(defaultPath)) {
config.cliPath = defaultPath;
} else {
throw new Error(
'cliPath must be defined. Either set the CLI_PATH environment variable or use the --cliPath flag to pass it in.'
);
}
}

if (!config.githubToken)
if (!config.personalAccessKey) {
throw new Error(
'githubToken must be defined. Either set the GITHUB_TOKEN environment variable, or use the --githubToken flag to pass it in.'
'personalAccessKey must be defined. Either set the PERSONAL_ACCESS_KEY environment variable or use the --personalAccessKey flag to pass it in.'
);
}

if (config.debug) {
console.log('Config: ', config);
}

return config;
};

module.exports = {
getTestConfig,
setArgsOverrides,
setLocalTestOverrides,
};
6 changes: 2 additions & 4 deletions acceptance-tests/package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
{
"name": "acceptance-tests",
"version": "5.1.4-beta.2",
"version": "5.2.1-beta.12",
"description": "Acceptance tests for cli",
"private": true,
"author": "Mike Talley <mtalley@hubspot.com>",
"homepage": "https://github.com/HubSpot/hubspot-cli#readme",
"license": "ISC",
"main": "run-tests",
Expand All @@ -19,8 +18,7 @@
},
"scripts": {
"test": "./run-tests",
"test-headless": "./run-tests --headless",
"run-tests": "./run-tests"
"test-headless": "./run-tests --headless"
},
"bugs": {
"url": "https://github.com/HubSpot/hubspot-cli/issues"
Expand Down
Loading

0 comments on commit a9ca1fc

Please sign in to comment.