mirror of
https://github.com/anthropics/claude-code-action.git
synced 2026-01-22 22:44:13 +08:00
feat: integrate claude-code-base-action as local subaction (#285)
* feat: integrate claude-code-base-action as local subaction
- Copy claude-code-base-action into base-action/ directory
- Update action.yml to reference ./base-action instead of external repo
- Preserve complete base action structure for future refactoring
This eliminates the external dependency while maintaining modularity.
* feat: consolidate CI workflows and add version bump workflow
- Move base-action test workflows to main .github/workflows/
- Update workflow references to use ./base-action
- Add CI jobs for base-action (test, typecheck, prettier)
- Add bump-claude-code-version workflow for base-action
- Remove redundant .github directory from base-action
This consolidates all CI workflows in one place while maintaining
full test coverage for both the main action and base-action.
* tsc
* copy again
* fix tests
* fix: use absolute path for base-action reference
Replace relative path ./base-action with ${{ github.action_path }}/base-action
to ensure the action works correctly when used in other repositories.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: inline base-action execution to support usage in other repos
Replace uses: ./base-action with direct shell execution since GitHub Actions
doesn't support dynamic paths in composite actions. This ensures the action
works correctly when used in other repositories.
Changes:
- Install Claude Code globally before execution
- Run base-action's index.ts directly with bun
- Pass all required INPUT_* environment variables
- Maintain base-action for future separate publishing
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
114
base-action/test/prepare-prompt.test.ts
Normal file
114
base-action/test/prepare-prompt.test.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env bun
|
||||
|
||||
import { describe, test, expect, beforeEach, afterEach } from "bun:test";
|
||||
import { preparePrompt, type PreparePromptInput } from "../src/prepare-prompt";
|
||||
import { unlink, writeFile, readFile, stat } from "fs/promises";
|
||||
|
||||
describe("preparePrompt integration tests", () => {
|
||||
beforeEach(async () => {
|
||||
try {
|
||||
await unlink("/tmp/claude-action/prompt.txt");
|
||||
} catch {
|
||||
// Ignore if file doesn't exist
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
try {
|
||||
await unlink("/tmp/claude-action/prompt.txt");
|
||||
} catch {
|
||||
// Ignore if file doesn't exist
|
||||
}
|
||||
});
|
||||
|
||||
test("should create temporary prompt file when only prompt is provided", async () => {
|
||||
const input: PreparePromptInput = {
|
||||
prompt: "This is a test prompt",
|
||||
promptFile: "",
|
||||
};
|
||||
|
||||
const config = await preparePrompt(input);
|
||||
|
||||
expect(config.path).toBe("/tmp/claude-action/prompt.txt");
|
||||
expect(config.type).toBe("inline");
|
||||
|
||||
const fileContent = await readFile(config.path, "utf-8");
|
||||
expect(fileContent).toBe("This is a test prompt");
|
||||
|
||||
const fileStat = await stat(config.path);
|
||||
expect(fileStat.size).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
test("should use existing file when promptFile is provided", async () => {
|
||||
const testFilePath = "/tmp/test-prompt.txt";
|
||||
await writeFile(testFilePath, "Prompt from file");
|
||||
|
||||
const input: PreparePromptInput = {
|
||||
prompt: "",
|
||||
promptFile: testFilePath,
|
||||
};
|
||||
|
||||
const config = await preparePrompt(input);
|
||||
|
||||
expect(config.path).toBe(testFilePath);
|
||||
expect(config.type).toBe("file");
|
||||
|
||||
await unlink(testFilePath);
|
||||
});
|
||||
|
||||
test("should fail when neither prompt nor promptFile is provided", async () => {
|
||||
const input: PreparePromptInput = {
|
||||
prompt: "",
|
||||
promptFile: "",
|
||||
};
|
||||
|
||||
await expect(preparePrompt(input)).rejects.toThrow(
|
||||
"Neither 'prompt' nor 'prompt_file' was provided",
|
||||
);
|
||||
});
|
||||
|
||||
test("should fail when promptFile points to non-existent file", async () => {
|
||||
const input: PreparePromptInput = {
|
||||
prompt: "",
|
||||
promptFile: "/tmp/non-existent-file.txt",
|
||||
};
|
||||
|
||||
await expect(preparePrompt(input)).rejects.toThrow(
|
||||
"Prompt file '/tmp/non-existent-file.txt' does not exist.",
|
||||
);
|
||||
});
|
||||
|
||||
test("should fail when prompt is empty", async () => {
|
||||
const emptyFilePath = "/tmp/empty-prompt.txt";
|
||||
await writeFile(emptyFilePath, "");
|
||||
|
||||
const input: PreparePromptInput = {
|
||||
prompt: "",
|
||||
promptFile: emptyFilePath,
|
||||
};
|
||||
|
||||
await expect(preparePrompt(input)).rejects.toThrow("Prompt file is empty");
|
||||
|
||||
try {
|
||||
await unlink(emptyFilePath);
|
||||
} catch {
|
||||
// Ignore cleanup errors
|
||||
}
|
||||
});
|
||||
|
||||
test("should fail when both prompt and promptFile are provided", async () => {
|
||||
const testFilePath = "/tmp/test-prompt.txt";
|
||||
await writeFile(testFilePath, "Prompt from file");
|
||||
|
||||
const input: PreparePromptInput = {
|
||||
prompt: "This should cause an error",
|
||||
promptFile: testFilePath,
|
||||
};
|
||||
|
||||
await expect(preparePrompt(input)).rejects.toThrow(
|
||||
"Both 'prompt' and 'prompt_file' were provided. Please specify only one.",
|
||||
);
|
||||
|
||||
await unlink(testFilePath);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user