Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 25 additions & 3 deletions .envrc.example
Original file line number Diff line number Diff line change
@@ -1,19 +1,41 @@
#!/usr/bin/env bash

# API Configuration
# API Configuration (override defaults in src/config/constants.ts)
export GRAPHQL_HOST='https://api.nes.herodevs.com';
export GRAPHQL_PATH='/graphql';
export EOL_REPORT_URL='https://eol-report-card.apps.herodevs.com/reports';
export ANALYTICS_URL='https://eol-api.herodevs.com/track';

# OAuth (for hd auth login)
export OAUTH_CONNECT_URL='';
export OAUTH_CLIENT_ID='';
# export OAUTH_CALLBACK_PORT='4000';
# export OAUTH_CALLBACK_REDIRECT='http://localhost:4000/oauth2/callback';

# Performance tuning (optional)
# IAM (for CI token provisioning via hd auth provision-ci-token)
# export IAM_HOST='https://apps.herodevs.io/api/iam';
# export IAM_PATH='/graphql';

# Auth toggles (optional; both default false)
# export ENABLE_AUTH='true';
# export ENABLE_USER_SETUP='true';

# CI token (for headless flows)
# HD_ORG_ID: required when using HD_AUTH_TOKEN; also stored when provisioning
# HD_AUTH_TOKEN: refresh token from provision; exchanged for access token
# HD_ACCESS_TOKEN: direct access token (skips exchange)
# export HD_ORG_ID='1234';
# export HD_AUTH_TOKEN='<long-lived-refresh-token>';
# export HD_ACCESS_TOKEN='<access-token>';

# Performance (optional)
# export CONCURRENT_PAGE_REQUESTS='3';
# export PAGE_SIZE='500';

# Keyring configuration (optional, for debugging)
# Privacy
# export TRACKING_OPT_OUT='true';

# Keyring (optional; for debugging token storage)
# export HD_AUTH_SERVICE_NAME='@herodevs/cli';
# export HD_AUTH_ACCESS_KEY='access-token';
# export HD_AUTH_REFRESH_KEY='refresh-token';
118 changes: 115 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,58 @@ USAGE
<!-- usagestop -->
## Commands
<!-- commands -->
* [`hd auth login`](#hd-auth-login)
* [`hd auth logout`](#hd-auth-logout)
* [`hd auth provision-ci-token`](#hd-auth-provision-ci-token)
* [`hd help [COMMAND]`](#hd-help-command)
* [`hd report committers`](#hd-report-committers)
* [`hd scan eol`](#hd-scan-eol)
* [`hd tracker init`](#hd-tracker-init)
* [`hd tracker run`](#hd-tracker-run)
* [`hd update [CHANNEL]`](#hd-update-channel)
* **NOTE:** Only applies to [binary installation method](#binary-installation). NPM users should use [`npm install`](#global-npm-installation) to update to the latest version.
* **NOTE:** Only applies to [binary installation method](#binary-installation). NPM users should use [`npm install`](#global-npm-installation) to update to the latest version.

## `hd auth login`

OAuth CLI login

```
USAGE
$ hd auth login

DESCRIPTION
OAuth CLI login
```

_See code: [src/commands/auth/login.ts](https://github.com/herodevs/cli/blob/v2.0.0-beta.14/src/commands/auth/login.ts)_

## `hd auth logout`

Logs out of HeroDevs OAuth and clears stored tokens

```
USAGE
$ hd auth logout

DESCRIPTION
Logs out of HeroDevs OAuth and clears stored tokens
```

_See code: [src/commands/auth/logout.ts](https://github.com/herodevs/cli/blob/v2.0.0-beta.14/src/commands/auth/logout.ts)_

## `hd auth provision-ci-token`

Provision a CI/CD long-lived refresh token for headless auth

```
USAGE
$ hd auth provision-ci-token

DESCRIPTION
Provision a CI/CD long-lived refresh token for headless auth
```

_See code: [src/commands/auth/provision-ci-token.ts](https://github.com/herodevs/cli/blob/v2.0.0-beta.14/src/commands/auth/provision-ci-token.ts)_

## `hd help [COMMAND]`

Expand Down Expand Up @@ -121,10 +166,10 @@ USAGE
FLAGS
-c, --csv Output in CSV format
-d, --directory=<value> Directory to search
-e, --afterDate=<value> [default: 2025-02-02] Start date (format: yyyy-MM-dd)
-e, --afterDate=<value> [default: 2025-02-18] Start date (format: yyyy-MM-dd)
-m, --months=<value> [default: 12] The number of months of git history to review. Cannot be used along beforeDate
and afterDate
-s, --beforeDate=<value> [default: 2026-02-02] End date (format: yyyy-MM-dd)
-s, --beforeDate=<value> [default: 2026-02-18] End date (format: yyyy-MM-dd)
-s, --save Save the committers report as herodevs.committers.<output>
-x, --exclude=<value>... Path Exclusions (eg -x="./src/bin" -x="./dist")
--json Output to JSON format
Expand Down Expand Up @@ -301,6 +346,73 @@ _See code: [@oclif/plugin-update](https://github.com/oclif/plugin-update/blob/4.

You can use `@herodevs/cli` in your CI/CD pipelines to automate EOL scanning.

### CI/CD authentication

For headless use in CI/CD (e.g. GitHub Actions, GitLab CI), the CLI supports long-lived organization-scoped refresh tokens. You do not need to run an interactive login in the pipeline.

**One-time setup (interactive):**

```bash
hd auth login
hd auth provision-ci-token
```

Copy the token output, add as CI secrets: `HD_AUTH_TOKEN` and `HD_ORG_ID` (orgId is obtained from user setup and stored at provision time when using locally).

**CI pipeline (headless):** Run `hd scan eol` directly with `HD_AUTH_TOKEN` and `HD_ORG_ID` set. The CLI exchanges the token for an access token automatically:

```bash
export HD_ORG_ID=<id> HD_AUTH_TOKEN="<token>"
hd scan eol --dir .
```

| Secret / Env Var | Purpose |
|------------------|---------|
| `HD_AUTH_TOKEN` | Long-lived refresh token from provision |
| `HD_ORG_ID` | Organization ID (required when using HD_AUTH_TOKEN; also stored at provision time when using local file) |

#### Local testing

Reproduce the CI flow locally:

```bash
export HD_ORG_ID=1234 HD_AUTH_TOKEN="eyJ..."
hd scan eol --dir /path/to/project
```

#### GitHub Actions (authenticated scan)

Add secrets `HD_AUTH_TOKEN` and `HD_ORG_ID` in your repository or organization, then:

```yaml
- uses: actions/checkout@v5
- uses: actions/setup-node@v6
with:
node-version: '24'
- name: Run EOL Scan
env:
HD_ORG_ID: ${{ secrets.HD_ORG_ID }}
HD_AUTH_TOKEN: ${{ secrets.HD_AUTH_TOKEN }}
run: npx @herodevs/cli@beta scan eol -s
```

#### GitLab CI (authenticated scan)

Add CI/CD variables `HD_AUTH_TOKEN` and `HD_ORG_ID` (masked) in your project:

```yaml
eol-scan:
image: node:24
variables:
HD_ORG_ID: $HD_ORG_ID
HD_AUTH_TOKEN: $HD_AUTH_TOKEN
script:
- npx @herodevs/cli@beta scan eol -s
artifacts:
paths:
- herodevs.report.json
```

### Using the Docker Image (Recommended)

We provide a Docker image that's pre-configured to run EOL scans. Based on [`cdxgen`](https://github.com/CycloneDX/cdxgen),
Expand Down
2 changes: 1 addition & 1 deletion e2e/scan/eol.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ describe('scan:eol e2e', () => {
});

it('warns and skips saving when --sbomOutput is provided without --saveSbom', async () => {
const customDir = path.join(fixturesDir, 'sbom-outputs');
const customDir = path.join(tmpdir(), 'scan-eol-sbom-output', randomUUID());
const customPath = path.join(customDir, 'custom-sbom.json');
await mkdir(customDir, { recursive: true });

Expand Down
111 changes: 111 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"@oclif/plugin-update": "^4.7.16",
"@oclif/table": "^0.5.1",
"cli-progress": "^3.12.0",
"conf": "^15.1.0",
"date-fns": "^4.1.0",
"glob": "^13.0.0",
"graphql": "^16.11.0",
Expand Down
Loading