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
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ A GitHub Action to deploy agents to the [Runloop](https://runloop.ai) platform.

## Quick Start

### Deploy Current Repository as Agent
### Deploy Current Repository as an Agent

```yaml
- name: Deploy agent
uses: runloopai/deploy-agent@main
with:
api-key: ${{ secrets.RUNLOOP_API_KEY }}
source-type: git
agent-version: 1.0.0
```

That's it! The action will automatically use your current repository and commit SHA.
Expand All @@ -34,6 +35,7 @@ That's it! The action will automatically use your current repository and commit
|-------|----------|---------|-------------|
| `api-key` | ✅ | | Runloop API key (store in secrets) |
| `source-type` | ✅ | | Agent source type: `git`, `tar`, or `file` |
| `agent-version` | ✅ | | Agent version (semver string like `2.0.65` or git SHA) |
| `agent-name` | | repo name | Name for the agent (defaults to repository name) |
| `git-repository` | | current repo | Git repository URL (auto-detected) |
| `git-ref` | | current commit/tag | Git ref (branch/tag/commit SHA, auto-detected) |
Expand Down Expand Up @@ -63,6 +65,7 @@ That's it! The action will automatically use your current repository and commit
with:
api-key: ${{ secrets.RUNLOOP_API_KEY }}
source-type: git
agent-version: 1.0.0
setup-commands: |
chmod +x scripts/agent.sh
npm install
Expand All @@ -84,6 +87,7 @@ jobs:
with:
api-key: ${{ secrets.RUNLOOP_API_KEY }}
source-type: git
agent-version: ${{ github.event.release.tag_name }}
agent-name: my-agent-${{ github.event.release.tag_name }}
```

Expand All @@ -105,6 +109,7 @@ Basic example:
with:
api-key: ${{ secrets.RUNLOOP_API_KEY }}
source-type: tar
agent-version: 1.0.0
path: agent.tar.gz
object-ttl-days: 30
```
Expand All @@ -123,6 +128,7 @@ You can also use `.tar` format or reference output from a previous step:
with:
api-key: ${{ secrets.RUNLOOP_API_KEY }}
source-type: tar
agent-version: 1.0.0
path: ${{ steps.build.outputs.archive-path }}
```

Expand All @@ -133,6 +139,7 @@ You can also use `.tar` format or reference output from a previous step:
with:
api-key: ${{ secrets.RUNLOOP_API_KEY }}
source-type: file
agent-version: 1.0.0
path: ./scripts/agent.sh
```

Expand Down
1 change: 1 addition & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ inputs:
object-ttl-days:
description: 'Time-to-live for uploaded objects in days (optional)'
required: false
# default is 'undefined' => don't auto-delete

outputs:
agent-id:
Expand Down
14 changes: 5 additions & 9 deletions dist/index.js

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

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions examples/git-auto.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ jobs:
with:
api-key: ${{ secrets.RUNLOOP_API_KEY }}
source-type: git
agent-version: 1.0.0
# agent-name defaults to repository name if not provided
# git-repository defaults to current repository
# git-ref defaults to current commit SHA
Expand Down
1 change: 1 addition & 0 deletions examples/git-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ jobs:
with:
api-key: ${{ secrets.RUNLOOP_API_KEY }}
source-type: git
agent-version: ${{ github.event.release.tag_name }}
agent-name: my-agent-${{ github.event.release.tag_name }}
# git-ref automatically uses the release tag
setup-commands: |
Expand Down
1 change: 1 addition & 0 deletions examples/single-file.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ jobs:
with:
api-key: ${{ secrets.RUNLOOP_API_KEY }}
source-type: file
agent-version: 1.0.0
agent-name: my-script-agent
path: ./scripts/agent.sh # Path to single file
setup-commands: |
Expand Down
5 changes: 5 additions & 0 deletions examples/tar-agent.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ jobs:
with:
api-key: ${{ secrets.RUNLOOP_API_KEY }}
source-type: tar
agent-version: 1.0.0
path: agent.tar.gz
agent-name: my-tar-agent
setup-commands: |
Expand Down Expand Up @@ -82,6 +83,7 @@ jobs:
with:
api-key: ${{ secrets.RUNLOOP_API_KEY }}
source-type: tar
agent-version: ${{ steps.build.outputs.agent-version }}
path: ${{ steps.build.outputs.archive-path }}
agent-name: built-agent-${{ steps.build.outputs.agent-version }}

Expand All @@ -102,6 +104,7 @@ jobs:
with:
api-key: ${{ secrets.RUNLOOP_API_KEY }}
source-type: tar
agent-version: 1.0.0
path: agent.tar

deploy-with-exclusions:
Expand All @@ -128,6 +131,7 @@ jobs:
with:
api-key: ${{ secrets.RUNLOOP_API_KEY }}
source-type: tar
agent-version: 1.0.0
path: agent.tar.gz
object-ttl-days: 30
is-public: false
Expand All @@ -150,4 +154,5 @@ jobs:
with:
api-key: ${{ secrets.RUNLOOP_API_KEY }}
source-type: tar
agent-version: 1.0.0
path: ./artifacts/agent.tar.gz
15 changes: 5 additions & 10 deletions src/validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,11 @@ export function validateInputs(inputs: ActionInputs): void {
}

function validatePath(inputPath: string, sourceType: SourceType): void {
// Resolve path relative to workspace
const workspace = process.env.GITHUB_WORKSPACE;
if (!workspace) {
throw new Error('GITHUB_WORKSPACE environment variable is not set');
if (sourceType !== 'file' && sourceType !== 'tar') {
throw new Error(`validatePath is undefined when source-type is "${sourceType}": ${inputPath}`);
}

const absolutePath = path.isAbsolute(inputPath) ? inputPath : path.join(workspace, inputPath);
const absolutePath = resolvePath(inputPath);

// Check if path exists
if (!fs.existsSync(absolutePath)) {
Expand All @@ -110,11 +108,8 @@ function validatePath(inputPath: string, sourceType: SourceType): void {

// Validate based on source type
const stats = fs.statSync(absolutePath);

if (sourceType === 'file' || sourceType === 'tar') {
if (!stats.isFile()) {
throw new Error(`Path must be a file when source-type is "${sourceType}": ${inputPath}`);
}
if (!stats.isFile()) {
throw new Error(`Path must be a file when source-type is "${sourceType}": ${inputPath}`);
}
}

Expand Down