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
153 changes: 153 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
name: Test Action

on:
push:
branches: [main]
pull_request:

jobs:
test-latest:
name: Install latest
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Run setup-devhelm
id: setup
uses: ./
with:
devhelm-version: latest

- name: Verify devhelm is on PATH
run: which devhelm

- name: Verify version output
run: |
VERSION="${{ steps.setup.outputs.devhelm-version }}"
echo "Reported version: $VERSION"
[[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+ ]] || { echo "::error::Invalid version format: $VERSION"; exit 1; }

- name: Verify CLI runs
run: devhelm --help

- name: Verify validate works without API
run: |
devhelm init --force
devhelm validate devhelm.yml

test-pinned:
name: Install pinned version
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Run setup-devhelm
id: setup
uses: ./
with:
devhelm-version: '0.1.4'

- name: Verify exact version
run: |
EXPECTED="0.1.4"
ACTUAL="${{ steps.setup.outputs.devhelm-version }}"
echo "Expected: $EXPECTED, Got: $ACTUAL"
[[ "$ACTUAL" == "$EXPECTED" ]] || { echo "::error::Version mismatch: expected $EXPECTED, got $ACTUAL"; exit 1; }

test-env-export:
name: Environment variables
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Run setup-devhelm with env inputs
uses: ./
with:
api-token: test-token-value
api-url: https://api.staging.devhelm.io
org-id: '42'
workspace-id: '7'

- name: Verify DEVHELM_API_TOKEN
run: |
[[ "$DEVHELM_API_TOKEN" == "test-token-value" ]] || { echo "::error::DEVHELM_API_TOKEN not set"; exit 1; }

- name: Verify DEVHELM_API_URL
run: |
[[ "$DEVHELM_API_URL" == "https://api.staging.devhelm.io" ]] || { echo "::error::DEVHELM_API_URL not set"; exit 1; }

- name: Verify DEVHELM_ORG_ID
run: |
[[ "$DEVHELM_ORG_ID" == "42" ]] || { echo "::error::DEVHELM_ORG_ID not set"; exit 1; }

- name: Verify DEVHELM_WORKSPACE_ID
run: |
[[ "$DEVHELM_WORKSPACE_ID" == "7" ]] || { echo "::error::DEVHELM_WORKSPACE_ID not set"; exit 1; }

test-no-env-when-empty:
name: No env vars when inputs are empty
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Run setup-devhelm without auth inputs
uses: ./

- name: Verify no DEVHELM_API_TOKEN
run: |
[[ -z "$DEVHELM_API_TOKEN" ]] || { echo "::error::DEVHELM_API_TOKEN should not be set"; exit 1; }

- name: Verify no DEVHELM_ORG_ID
run: |
[[ -z "$DEVHELM_ORG_ID" ]] || { echo "::error::DEVHELM_ORG_ID should not be set"; exit 1; }

test-skip-node-setup:
name: Skip built-in Node setup
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 22

- name: Run setup-devhelm without auto Node
id: setup
uses: ./
with:
node-version: ''

- name: Verify Node version unchanged
run: |
NODE_V=$(node -v)
echo "Node version: $NODE_V"
[[ "$NODE_V" == v22.* ]] || { echo "::error::Expected Node 22.x, got $NODE_V"; exit 1; }

- name: Verify devhelm works
run: devhelm --help

test-macos:
name: Install on macOS
runs-on: macos-latest
steps:
- uses: actions/checkout@v4

- name: Run setup-devhelm
id: setup
uses: ./

- name: Verify CLI runs
run: devhelm --help

test-cache:
name: Cache behavior
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Run setup-devhelm
id: setup
uses: ./

- name: Report cache status
run: echo "Cache hit = ${{ steps.setup.outputs.cache-hit }}"
110 changes: 110 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# setup-devhelm

GitHub Action to install and configure the [DevHelm CLI](https://www.npmjs.com/package/devhelm) for monitoring-as-code workflows.

## Usage

### Basic — validate config on PRs

```yaml
- uses: actions/checkout@v4
- uses: devhelmhq/setup-devhelm@v1
- run: devhelm validate
```

### Pin a specific version

```yaml
- uses: devhelmhq/setup-devhelm@v1
with:
devhelm-version: '0.1.4'
```

### Authenticate and verify

```yaml
- uses: devhelmhq/setup-devhelm@v1
with:
api-token: ${{ secrets.DEVHELM_API_TOKEN }}
org-id: ${{ vars.DEVHELM_ORG_ID }}
workspace-id: ${{ vars.DEVHELM_WORKSPACE_ID }}
verify-connection: true
```

### Full CI/CD example

```yaml
name: DevHelm Monitoring as Code

on:
push:
branches: [main]
paths: ['devhelm.yml']
pull_request:
paths: ['devhelm.yml']

jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: devhelmhq/setup-devhelm@v1
- run: devhelm validate

deploy:
if: github.ref == 'refs/heads/main'
needs: validate
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: devhelmhq/setup-devhelm@v1
with:
api-token: ${{ secrets.DEVHELM_API_TOKEN }}
org-id: ${{ vars.DEVHELM_ORG_ID }}
workspace-id: ${{ vars.DEVHELM_WORKSPACE_ID }}
verify-connection: true
- run: devhelm deploy devhelm.yml
- run: devhelm status --output json
```

## Inputs

| Input | Required | Default | Description |
|-------|----------|---------|-------------|
| `devhelm-version` | No | `latest` | CLI version — exact semver (e.g. `0.1.4`) or `latest` |
| `api-token` | No | — | DevHelm API token. Pass via `secrets.DEVHELM_API_TOKEN` |
| `api-url` | No | — | API base URL (default: `https://api.devhelm.io`) |
| `org-id` | No | — | Organization ID for multi-org accounts |
| `workspace-id` | No | — | Workspace ID for multi-workspace accounts |
| `verify-connection` | No | `false` | Run `devhelm auth me` after setup to verify credentials |
| `node-version` | No | `20` | Node.js version. Set to `''` to skip if you manage Node yourself |

## Outputs

| Output | Description |
|--------|-------------|
| `devhelm-version` | Installed CLI version (e.g. `0.1.4`) |
| `cache-hit` | `true` if the npm cache was restored |

## How it works

1. **Node.js** — ensures Node >= 18 is available (auto-installs via `actions/setup-node` unless you set `node-version: ''`)
2. **Cache** — restores `~/.npm` cache keyed on OS + CLI version
3. **Install** — runs `npm install -g devhelm@<version>`
4. **Environment** — exports `DEVHELM_API_TOKEN`, `DEVHELM_API_URL`, `DEVHELM_ORG_ID`, `DEVHELM_WORKSPACE_ID` for all subsequent steps
5. **Verify** — optionally runs `devhelm auth me` to fail fast on bad credentials

## Security

- **Never hardcode tokens** in workflow files. Use [GitHub Secrets](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions).
- The `api-token` input is passed through environment variables, never logged.
- For org/workspace IDs (non-sensitive), use [GitHub Variables](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables).

## Requirements

- **Node.js >= 18** — the action auto-installs Node 20 by default. Set `node-version: ''` if your workflow already provides Node.
- **npm** — ships with Node.js.

## License

MIT — see [LICENSE](LICENSE).
104 changes: 104 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
name: 'Setup DevHelm CLI'
description: 'Install and configure the DevHelm CLI for monitoring-as-code workflows'
author: 'DevHelm'

branding:
icon: terminal
color: blue

inputs:
devhelm-version:
description: 'CLI version to install — exact semver (e.g. "0.1.4") or "latest"'
required: false
default: 'latest'
api-token:
description: 'DevHelm API token (recommended: pass via secrets.DEVHELM_API_TOKEN)'
required: false
api-url:
description: 'DevHelm API base URL (default: https://api.devhelm.io)'
required: false
org-id:
description: 'Organization ID for multi-org accounts'
required: false
workspace-id:
description: 'Workspace ID for multi-workspace accounts'
required: false
verify-connection:
description: 'Run "devhelm auth me" after setup to verify credentials work'
required: false
default: 'false'
node-version:
description: 'Node.js version to use if actions/setup-node was not called before this action. Set to empty string to skip auto-setup.'
required: false
default: '20'

outputs:
devhelm-version:
description: 'Installed CLI version (semver only, e.g. "0.1.4")'
value: ${{ steps.install.outputs.version }}
cache-hit:
description: 'Whether the npm cache was restored'
value: ${{ steps.cache.outputs.cache-hit }}

runs:
using: composite
steps:
- name: Ensure Node.js is available
if: inputs.node-version != ''
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}

- name: Validate Node.js
shell: bash
run: |
if ! command -v node &>/dev/null; then
echo "::error::Node.js is required. Either set input 'node-version' or run actions/setup-node before this action."
exit 1
fi
NODE_MAJOR=$(node -v | sed 's/v\([0-9]*\).*/\1/')
if (( NODE_MAJOR < 18 )); then
echo "::error::DevHelm CLI requires Node.js >= 18 (found $(node -v))"
exit 1
fi

- name: Restore npm cache
id: cache
uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-devhelm-${{ inputs.devhelm-version }}

- name: Install DevHelm CLI
id: install
shell: bash
run: |
echo "::group::Installing devhelm@${{ inputs.devhelm-version }}"
npm install -g devhelm@${{ inputs.devhelm-version }} 2>&1
echo "::endgroup::"

RAW=$(devhelm --version)
VERSION=$(echo "$RAW" | awk '{print $1}' | sed 's|.*/||')
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "Installed devhelm $VERSION"

- name: Export environment variables
shell: bash
env:
INPUT_TOKEN: ${{ inputs.api-token }}
INPUT_URL: ${{ inputs.api-url }}
INPUT_ORG: ${{ inputs.org-id }}
INPUT_WS: ${{ inputs.workspace-id }}
run: |
[[ -n "$INPUT_TOKEN" ]] && echo "DEVHELM_API_TOKEN=$INPUT_TOKEN" >> "$GITHUB_ENV"
[[ -n "$INPUT_URL" ]] && echo "DEVHELM_API_URL=$INPUT_URL" >> "$GITHUB_ENV"
[[ -n "$INPUT_ORG" ]] && echo "DEVHELM_ORG_ID=$INPUT_ORG" >> "$GITHUB_ENV"
[[ -n "$INPUT_WS" ]] && echo "DEVHELM_WORKSPACE_ID=$INPUT_WS" >> "$GITHUB_ENV"
exit 0

- name: Verify connection
if: inputs.verify-connection == 'true' && inputs.api-token != ''
shell: bash
run: |
echo "Verifying DevHelm API connection..."
devhelm auth me --output json
Loading