Skip to content

Use Kubernetes CronJob for cron-based TaskSpawners#449

Merged
gjkim42 merged 1 commit intomainfrom
axon-task-430
Feb 27, 2026
Merged

Use Kubernetes CronJob for cron-based TaskSpawners#449
gjkim42 merged 1 commit intomainfrom
axon-task-430

Conversation

@axon-agent
Copy link

@axon-agent axon-agent bot commented Feb 26, 2026

Summary

  • Replace custom cron polling logic in TaskSpawner with native Kubernetes CronJob scheduling
  • When spec.when.cron is set, the controller now creates a CronJob (not a Deployment) that runs the spawner in one-shot mode on the cron schedule itself
  • This eliminates the confusing pollInterval + cron schedule overlap (closes Re implement TaskSpawnwer's cron #430, related to having pollinterval and cron doesn't make sense #138)
  • Add --one-shot flag to the spawner binary for single-cycle execution used by CronJob pods
  • Add status.cronJobName field to track the CronJob resource
  • Add tests for CronJob building, schedule updates, suspend toggle, and stale resource cleanup
  • Clean up stale Deployment/CronJob when switching between polling and cron modes to prevent duplicate task spawning

Test plan

  • make verify passes
  • make test passes (all unit tests including new stale resource cleanup tests)
  • CI e2e tests pass
  • Manual testing: create a TaskSpawner with when.cron and verify CronJob is created
  • Manual testing: verify suspend/resume toggles CronJob .spec.suspend
  • Manual testing: verify schedule updates propagate to CronJob
  • Manual testing: switch a TaskSpawner from polling to cron and verify old Deployment is cleaned up

🤖 Generated with Claude Code

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 10 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="internal/controller/taskspawner_controller.go">

<violation number="1" location="internal/controller/taskspawner_controller.go:91">
P2: Cron-based reconciliation doesn’t clean up an existing Deployment when a TaskSpawner is switched from polling to cron, so the old Deployment keeps running and can spawn duplicate tasks. Add a cleanup step before creating/updating the CronJob.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

@gjkim42 gjkim42 force-pushed the axon-task-430 branch 2 times, most recently from 176ca44 to a3dd3e3 Compare February 27, 2026 16:33
Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 13 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="internal/controller/taskspawner_controller.go">

<violation number="1" location="internal/controller/taskspawner_controller.go:259">
P2: When switching between cron and polling modes, stale status fields are not cleared. `reconcileCronJob` sets `CronJobName` but doesn't clear `DeploymentName`, and vice versa. After a mode switch, the status will reference a deleted resource, which could confuse users and tooling.</violation>

<violation number="2" location="internal/controller/taskspawner_controller.go:399">
P0: Bug: `reconcileCronJob` never resolves the workspace or detects GitHub App auth, and `BuildCronJob` hardcodes `nil`/`false` for these. CronJob-based TaskSpawners that reference a workspace will be missing `--github-owner`, `--github-repo` args, and all GitHub auth (PAT env var or token-refresher sidecar), causing them to fail at runtime.

`reconcileCronJob` needs workspace resolution logic (same as `reconcileDeployment`), `BuildCronJob` needs to accept `workspace` and `isGitHubApp` parameters, and the call sites in `createCronJob`/`updateCronJob` need to pass them through.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

@gjkim42 gjkim42 added priority/important-longterm triage-accepted kind/feature Categorizes issue or PR as related to a new feature labels Feb 27, 2026
@github-actions github-actions bot removed needs-triage needs-kind Indicates an issue or PR lacks a kind/* label needs-priority labels Feb 27, 2026
Replace the custom cron polling logic with native Kubernetes CronJob
scheduling. Previously, cron-based TaskSpawners ran a long-lived
Deployment that polled on pollInterval and computed missed cron ticks.
This was confusing because pollInterval and cron schedule served
overlapping purposes (issue #138).

Now, when spec.when.cron is set, the controller creates a CronJob
instead of a Deployment. The CronJob runs on the cron schedule itself,
executing the spawner binary in one-shot mode (--one-shot flag) which
runs a single discovery cycle and exits. This eliminates the need for
pollInterval for cron use cases and delegates scheduling to Kubernetes.

Key changes:
- Add --one-shot flag to axon-spawner binary for single-cycle execution
- Add BuildCronJob method to DeploymentBuilder for creating CronJobs
- Split controller reconciliation into reconcileDeployment (GitHub/Jira)
  and reconcileCronJob (cron) paths
- Add status.cronJobName field to TaskSpawnerStatus
- Add RBAC for batch/cronjobs and watch CronJobs in SetupWithManager
- Add tests for CronJob builder, schedule updates, and suspend toggle

Closes #430
Related: #138

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gjkim42 gjkim42 enabled auto-merge February 27, 2026 17:09
@gjkim42 gjkim42 added this pull request to the merge queue Feb 27, 2026
Merged via the queue into main with commit 1bdca18 Feb 27, 2026
6 checks passed
@gjkim42 gjkim42 deleted the axon-task-430 branch February 27, 2026 17:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Re implement TaskSpawnwer's cron

1 participant