Skip to content

Commit b9361f4

Browse files
committed
first version of github actions
1 parent 68c2cee commit b9361f4

2 files changed

Lines changed: 137 additions & 22 deletions

File tree

codeflash/cli_cmds/cmd_init.py

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,13 @@
2626
from codeflash.cli_cmds.cli_common import apologize_and_exit
2727
from codeflash.cli_cmds.console import console, logger
2828
from codeflash.cli_cmds.extension import install_vscode_extension
29+
2930
# Import JS/TS init module
3031
from codeflash.cli_cmds.init_javascript import (
31-
JsPackageManager,
32-
JSSetupInfo,
3332
ProjectLanguage,
3433
detect_project_language,
3534
determine_js_package_manager,
36-
get_js_codeflash_command,
3735
get_js_dependency_installation_commands,
38-
get_js_runtime_setup_string,
3936
init_js_project,
4037
)
4138
from codeflash.code_utils.code_utils import validate_relative_directory_path
@@ -798,8 +795,16 @@ def install_github_actions(override_formatter_check: bool = False) -> None: # n
798795

799796
# Generate workflow content AFTER user confirmation
800797
logger.info("[cmd_init.py:install_github_actions] User confirmed, generating workflow content...")
798+
799+
# Select the appropriate workflow template based on project language
800+
project_language = detect_project_language_for_workflow(Path.cwd())
801+
if project_language in ("javascript", "typescript"):
802+
workflow_template = "codeflash-optimize-js.yaml"
803+
else:
804+
workflow_template = "codeflash-optimize.yaml"
805+
801806
optimize_yml_content = (
802-
files("codeflash").joinpath("cli_cmds", "workflows", "codeflash-optimize.yaml").read_text(encoding="utf-8")
807+
files("codeflash").joinpath("cli_cmds", "workflows", workflow_template).read_text(encoding="utf-8")
803808
)
804809
materialized_optimize_yml_content = generate_dynamic_workflow_content(
805810
optimize_yml_content, config, git_root, benchmark_mode
@@ -1337,7 +1342,15 @@ def generate_dynamic_workflow_content(
13371342
module_path = str(Path(config["module_root"]).relative_to(git_root) / "**")
13381343
optimize_yml_content = optimize_yml_content.replace("{{ codeflash_module_path }}", module_path)
13391344

1340-
# Get working directory
1345+
# Detect project language
1346+
project_language = detect_project_language_for_workflow(Path.cwd())
1347+
1348+
# For JavaScript/TypeScript projects, use static template customization
1349+
# (AI-generated steps are currently Python-only)
1350+
if project_language in ("javascript", "typescript"):
1351+
return customize_codeflash_yaml_content(optimize_yml_content, config, git_root, benchmark_mode)
1352+
1353+
# Python project - try AI-generated steps
13411354
toml_path = Path.cwd() / "pyproject.toml"
13421355
try:
13431356
with toml_path.open(encoding="utf8") as pyproject_file:
@@ -1503,13 +1516,20 @@ def _customize_python_workflow_content(
15031516
codeflash_cmd += " --benchmark"
15041517
return optimize_yml_content.replace("{{ codeflash_command }}", codeflash_cmd)
15051518

1506-
# TODO:{claude} Refactor and move to support for language specific
1519+
# TODO:{claude} Refactor and move to support for language specific
15071520
def _customize_js_workflow_content(
15081521
optimize_yml_content: str,
15091522
git_root: Path,
15101523
benchmark_mode: bool = False, # noqa: FBT001, FBT002
15111524
) -> str:
15121525
"""Customize workflow content for JavaScript/TypeScript projects."""
1526+
from codeflash.cli_cmds.init_javascript import (
1527+
get_js_codeflash_install_step,
1528+
get_js_codeflash_run_command,
1529+
get_js_runtime_setup_steps,
1530+
is_codeflash_dependency,
1531+
)
1532+
15131533
project_root = Path.cwd()
15141534
package_json_path = project_root / "package.json"
15151535

@@ -1531,19 +1551,24 @@ def _customize_js_workflow_content(
15311551

15321552
optimize_yml_content = optimize_yml_content.replace("{{ working_directory }}", working_dir)
15331553

1534-
# Determine package manager
1554+
# Determine package manager and codeflash dependency status
15351555
pkg_manager = determine_js_package_manager(project_root)
1556+
codeflash_is_dep = is_codeflash_dependency(project_root)
15361557

1537-
# Setup runtime environment
1538-
runtime_setup = get_js_runtime_setup_string(pkg_manager)
1539-
optimize_yml_content = optimize_yml_content.replace("{{ setup_runtime_environment }}", runtime_setup)
1558+
# Setup runtime environment (Node.js/Bun)
1559+
runtime_setup = get_js_runtime_setup_steps(pkg_manager)
1560+
optimize_yml_content = optimize_yml_content.replace("{{ setup_runtime_steps }}", runtime_setup)
15401561

15411562
# Install dependencies
15421563
install_deps_cmd = get_js_dependency_installation_commands(pkg_manager)
15431564
optimize_yml_content = optimize_yml_content.replace("{{ install_dependencies_command }}", install_deps_cmd)
15441565

1545-
# Codeflash command
1546-
codeflash_cmd = get_js_codeflash_command(pkg_manager)
1566+
# Install codeflash step (only if not a dependency)
1567+
install_codeflash = get_js_codeflash_install_step(pkg_manager, is_dependency=codeflash_is_dep)
1568+
optimize_yml_content = optimize_yml_content.replace("{{ install_codeflash_step }}", install_codeflash)
1569+
1570+
# Codeflash run command
1571+
codeflash_cmd = get_js_codeflash_run_command(pkg_manager, is_dependency=codeflash_is_dep)
15471572
if benchmark_mode:
15481573
codeflash_cmd += " --benchmark"
15491574
return optimize_yml_content.replace("{{ codeflash_command }}", codeflash_cmd)

codeflash/cli_cmds/init_javascript.py

Lines changed: 99 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -516,37 +516,127 @@ def configure_package_json(setup_info: JSSetupInfo) -> bool:
516516
# ============================================================================
517517

518518

519-
def get_js_runtime_setup_string(pkg_manager: JsPackageManager) -> str:
520-
"""Generate the appropriate Node.js setup step for GitHub Actions."""
519+
def is_codeflash_dependency(project_root: Path) -> bool:
520+
"""Check if codeflash is listed as a dependency in package.json."""
521+
package_json_path = project_root / "package.json"
522+
if not package_json_path.exists():
523+
return False
524+
525+
try:
526+
with package_json_path.open(encoding="utf8") as f:
527+
package_data = json.load(f)
528+
except (json.JSONDecodeError, OSError):
529+
return False
530+
531+
deps = package_data.get("dependencies", {})
532+
dev_deps = package_data.get("devDependencies", {})
533+
return "codeflash" in deps or "codeflash" in dev_deps
534+
535+
536+
def get_js_runtime_setup_steps(pkg_manager: JsPackageManager) -> str:
537+
"""Generate the appropriate Node.js/Bun setup steps for GitHub Actions.
538+
539+
Returns properly indented YAML steps for the workflow template.
540+
"""
521541
if pkg_manager == JsPackageManager.BUN:
522-
return """name: 🥟 Setup Bun
542+
return """- name: 🥟 Setup Bun
523543
uses: oven-sh/setup-bun@v2
524544
with:
525545
bun-version: latest"""
546+
526547
if pkg_manager == JsPackageManager.PNPM:
527-
return """name: 📦 Setup pnpm
548+
return """- name: 📦 Setup pnpm
528549
uses: pnpm/action-setup@v4
529550
with:
530551
version: 9
531552
- name: 🟢 Setup Node.js
532553
uses: actions/setup-node@v4
533554
with:
534-
node-version: '20'
555+
node-version: '22'
535556
cache: 'pnpm'"""
557+
536558
if pkg_manager == JsPackageManager.YARN:
537-
return """name: 🟢 Setup Node.js
559+
return """- name: 🟢 Setup Node.js
538560
uses: actions/setup-node@v4
539561
with:
540-
node-version: '20'
562+
node-version: '22'
541563
cache: 'yarn'"""
564+
542565
# NPM or UNKNOWN
543-
return """name: 🟢 Setup Node.js
566+
return """- name: 🟢 Setup Node.js
544567
uses: actions/setup-node@v4
545568
with:
546-
node-version: '20'
569+
node-version: '22'
547570
cache: 'npm'"""
548571

549572

573+
def get_js_codeflash_install_step(pkg_manager: JsPackageManager, *, is_dependency: bool) -> str:
574+
"""Generate the codeflash installation step if not already a dependency.
575+
576+
Args:
577+
pkg_manager: The package manager being used.
578+
is_dependency: Whether codeflash is already in package.json dependencies.
579+
580+
Returns:
581+
YAML step string for installing codeflash, or empty string if not needed.
582+
583+
"""
584+
if is_dependency:
585+
# Codeflash will be installed with other dependencies
586+
return ""
587+
588+
# Need to install codeflash separately
589+
if pkg_manager == JsPackageManager.BUN:
590+
return """- name: 📥 Install Codeflash
591+
run: bun add -g codeflash"""
592+
593+
if pkg_manager == JsPackageManager.PNPM:
594+
return """- name: 📥 Install Codeflash
595+
run: pnpm add -g codeflash"""
596+
597+
if pkg_manager == JsPackageManager.YARN:
598+
return """- name: 📥 Install Codeflash
599+
run: yarn global add codeflash"""
600+
601+
# NPM or UNKNOWN
602+
return """- name: 📥 Install Codeflash
603+
run: npm install -g codeflash"""
604+
605+
606+
def get_js_codeflash_run_command(pkg_manager: JsPackageManager, *, is_dependency: bool) -> str:
607+
"""Generate the codeflash run command for GitHub Actions.
608+
609+
Args:
610+
pkg_manager: The package manager being used.
611+
is_dependency: Whether codeflash is in package.json dependencies.
612+
613+
Returns:
614+
Command string to run codeflash.
615+
616+
"""
617+
if is_dependency:
618+
# Use package manager's run command for local dependency
619+
if pkg_manager == JsPackageManager.BUN:
620+
return "bun run codeflash"
621+
if pkg_manager == JsPackageManager.PNPM:
622+
return "pnpm exec codeflash"
623+
if pkg_manager == JsPackageManager.YARN:
624+
return "yarn codeflash"
625+
# NPM
626+
return "npx codeflash"
627+
628+
# Globally installed - just run directly
629+
return "codeflash"
630+
631+
632+
def get_js_runtime_setup_string(pkg_manager: JsPackageManager) -> str:
633+
"""Generate the appropriate Node.js setup step for GitHub Actions.
634+
635+
Deprecated: Use get_js_runtime_setup_steps instead.
636+
"""
637+
return get_js_runtime_setup_steps(pkg_manager)
638+
639+
550640
def get_js_dependency_installation_commands(pkg_manager: JsPackageManager) -> str:
551641
"""Generate commands to install JavaScript/TypeScript dependencies."""
552642
if pkg_manager == JsPackageManager.BUN:

0 commit comments

Comments
 (0)