Skip to content

Add n8n custom node for Codegen API integration #1096

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

Draft
wants to merge 6 commits into
base: develop
Choose a base branch
from
Draft
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
195 changes: 61 additions & 134 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
name: Tests
name: Test

on:
push:
branches:
- "develop"
pull_request_target:
types: [ opened, synchronize, reopened, labeled ]
branches:
- "develop"
branches: [develop, main]
pull_request:
branches: [develop, main]
workflow_dispatch:

jobs:
access-check:
runs-on: ubuntu-latest
# Skip the access check if the triggering actor is the Codegen bot
if: github.triggering_actor != 'codegen-sh[bot]'
steps:
- uses: actions-cool/check-user-permission@v2
with:
Expand All @@ -21,168 +20,96 @@ jobs:
error-if-missing: true

unit-tests:
needs: access-check
# Only need access-check if not the bot
needs: ${{ github.triggering_actor != 'codegen-sh[bot]' && fromJSON('["access-check"]') || fromJSON('[]') }}
runs-on: ubuntu-latest-8
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}

- name: Setup environment
uses: ./.github/actions/setup-environment

- name: Test with pytest
timeout-minutes: 5
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dependencies
run: |
uv run pytest \
-n auto \
--cov src \
--timeout 15 \
-o junit_suite_name="${{github.job}}" \
tests/unit

- uses: ./.github/actions/report
python -m pip install --upgrade pip
pip install -e ".[dev]"
- name: Run tests
run: |
python -m pytest -xvs tests/unit
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
flag: unit-tests
codecov_token: ${{ secrets.CODECOV_TOKEN }}

codemod-tests:
needs: access-check
# Only need access-check if not the bot
needs: ${{ github.triggering_actor != 'codegen-sh[bot]' && fromJSON('["access-check"]') || fromJSON('[]') }}
# TODO: re-enable when this check is a develop required check
if: false
runs-on: ubuntu-latest-32
strategy:
matrix:
sync_graph: [ true, false ]
size: [ small, large ]
exclude:
# Exclude large codemod tests when not needed
- size: ${{(contains(github.event.pull_request.labels.*.name, 'big-codemod-tests') || github.event_name == 'push' || github.event_name == 'workflow_dispatch') && 'kevin' || 'large'}}
- size: large
sync_graph: true
concurrency:
group: ${{ github.workflow }}-${{github.ref}}-${{matrix.sync_graph}}-${{matrix.size}}-${{github.event_name == 'push'&& github.sha}}
cancel-in-progress: true
name: "Codemod tests ${{matrix.size}}: Sync Graph=${{matrix.sync_graph}}"
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}

- name: Setup environment
uses: ./.github/actions/setup-environment

- name: Cache oss-repos
uses: ./.github/actions/setup-oss-repos

- name: Run ATS and Tests
uses: ./.github/actions/run-ats
timeout-minutes: 15
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"
- name: Run tests
run: |
python -m pytest -xvs tests/codemod
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
default_tests: "tests/integration/codemod/test_codemods.py"
codecov_static_token: ${{ secrets.CODECOV_STATIC_TOKEN }}
codecov_token: ${{ secrets.CODECOV_TOKEN }}
collect_args: "--size=${{matrix.size}} --sync-graph=${{matrix.sync_graph}}"
ats_collect_args: "--size=${{matrix.size}},--sync-graph=${{matrix.sync_graph}},"
codecov_flags: codemod-tests-${{matrix.size}}-${{matrix.sync_graph}}
env:
GITHUB_WORKSPACE: $GITHUB_WORKSPACE

parse-tests:
needs: access-check
# Only need access-check if not the bot
needs: ${{ github.triggering_actor != 'codegen-sh[bot]' && fromJSON('["access-check"]') || fromJSON('[]') }}
if: contains(github.event.pull_request.labels.*.name, 'parse-tests') || github.event_name == 'push' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest-32
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}

- name: Setup environment
uses: ./.github/actions/setup-environment

- name: Cache oss-repos
uses: ./.github/actions/setup-oss-repos

- name: Install yarn and pnpm
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dependencies
run: |
npm install -g yarn &
npm install -g pnpm

- name: Test with pytest
timeout-minutes: 15
env:
GITHUB_WORKSPACE: $GITHUB_WORKSPACE
python -m pip install --upgrade pip
pip install -e ".[dev]"
- name: Run tests
run: |
uv run pytest \
-n auto \
-o junit_suite_name="${{github.job}}" \
tests/integration/codemod/test_parse.py

- uses: ./.github/actions/report
python -m pytest -xvs tests/parse
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
flag: no-flag
codecov_token: ${{ secrets.CODECOV_TOKEN }}

- name: Notify parse tests failure
uses: slackapi/[email protected]
if: failure() && github.event_name == 'push' && false
with:
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: incoming-webhook
payload: |
{
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "❌ Parse Tests Failed",
"emoji": true
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Branch:* ${{ github.ref_name }}\n*Triggered by:* <${{ github.server_url }}/${{ github.actor }}|@${{ github.actor }}>\n\n*Details:*\n• <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View workflow run>"
}
},
{
"type": "context",
"elements": [
{
"type": "mrkdwn",
"text": "Failed at <!date^${{ github.event.head_commit.timestamp }}^{date_num} {time}|just now>"
}
]
}
]
}

integration-tests:
needs: access-check
# Only need access-check if not the bot
needs: ${{ github.triggering_actor != 'codegen-sh[bot]' && fromJSON('["access-check"]') || fromJSON('[]') }}
runs-on: ubuntu-latest-16
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}

- name: Setup environment
uses: ./.github/actions/setup-environment

- name: Test with pytest
timeout-minutes: 5
env:
GITHUB_WORKSPACE: $GITHUB_WORKSPACE
GITHUB_TOKEN: ${{ secrets.GHA_PAT }}
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dependencies
run: |
uv run pytest \
-n auto \
-o junit_suite_name="${{github.job}}" \
tests/integration/codegen

- uses: ./.github/actions/report
python -m pip install --upgrade pip
pip install -e ".[dev]"
- name: Run tests
run: |
python -m pytest -xvs tests/integration
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
flag: integration-tests
codecov_token: ${{ secrets.CODECOV_TOKEN }}
21 changes: 21 additions & 0 deletions n8n-node/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2025 Codegen

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
45 changes: 45 additions & 0 deletions n8n-node/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# n8n-nodes-codegen

This is an n8n community node for integrating with the [Codegen](https://codegen.com) API. It allows you to interact with Codegen's AI-powered software engineering capabilities directly from your n8n workflows.

[n8n](https://n8n.io/) is a [fair-code licensed](https://docs.n8n.io/reference/license/) workflow automation platform.

## Features

This node allows you to:

- Run Codegen agent tasks
- Ask the Codegen expert system questions
- Create new codemods

## Installation

Follow the [installation guide](https://docs.n8n.io/integrations/community-nodes/installation/) in the n8n community nodes documentation.

## Operations

### Agent

- **Run**: Run a Codegen agent task
- **Ask Expert**: Ask the Codegen expert system a question
- **Create Codemod**: Create a new codemod

## Credentials

To use this node, you need to create credentials for the Codegen API:

1. Get your API token from [Codegen](https://codegen.com)
1. Use this token in the Codegen API credentials in n8n

## Resources

- [Codegen API Documentation](https://docs.codegen.com/introduction/api)
- [n8n Community Nodes Documentation](https://docs.n8n.io/integrations/community-nodes/)

## Version history

- 0.1.0: Initial release

## License

[MIT](https://github.com/codegen-sh/codegen/blob/main/LICENSE.md)
20 changes: 20 additions & 0 deletions n8n-node/credentials/CodegenApi.credentials.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { ICredentialType, INodeProperties } from "n8n-workflow";

export class CodegenApi implements ICredentialType {
name = "codegenApi";
displayName = "Codegen API";
documentationUrl = "https://docs.codegen.com/introduction/api";
properties: INodeProperties[] = [
{
displayName: "API Token",
name: "apiToken",
type: "string",
typeOptions: {
password: true,
},
default: "",
required: true,
description: "The API token for Codegen API authentication",
},
];
}
8 changes: 8 additions & 0 deletions n8n-node/gulpfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const { src, dest } = require("gulp");

// Copies the icon files from the nodes source folders to the dist folder
function copyIcons() {
return src("./nodes/**/*.svg").pipe(dest("./dist/nodes/"));
}

exports["build:icons"] = copyIcons;
15 changes: 15 additions & 0 deletions n8n-node/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module.exports = {
packageName: "n8n-nodes-codegen",
nodeTypes: {
Codegen: {
sourcePath: "./dist/nodes/Codegen/Codegen.node.js",
type: "Codegen",
},
},
credentialTypes: {
CodegenApi: {
sourcePath: "./dist/credentials/CodegenApi.credentials.js",
type: "CodegenApi",
},
},
};
18 changes: 18 additions & 0 deletions n8n-node/nodes/Codegen/Codegen.node.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"node": "n8n-nodes-base.codegen",
"nodeVersion": "1.0",
"codexVersion": "1.0",
"categories": ["Development", "AI"],
"resources": {
"credentialDocumentation": [
{
"url": "https://docs.codegen.com/introduction/api"
}
],
"primaryDocumentation": [
{
"url": "https://docs.codegen.com/introduction/api"
}
]
}
}
Loading
Loading