-
Notifications
You must be signed in to change notification settings - Fork 48
Test asana webhook integration #4488
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
base: main
Are you sure you want to change the base?
Conversation
- Add /webhooks/github endpoint with signature verification - Implement pull_request event handler with support for: - opened: create Asana task - assigned/unassigned/edited: sync assignees - closed: mark task complete - reopened: reopen task - synchronize: no-op - Add structured logging and plan objects for observability
- Implement Asana task creation with GitHub login to Asana email mapping - Add task lookup by GitHub URL (custom field + notes fallback) - Implement task assignment and completion updates - Add PR description update with Asana task link - Use Asana Roster Project for user mapping
- Integrate Datadog metrics client - Track counters: tasks_created, tasks_completed, tasks_reopened, assign_updates, noops, mapping_failures - Track latency histograms for webhook processing and Asana API calls - Emit structured metrics with tags for filtering
- Implement exponential backoff with jitter (500ms-8s, max 3 retries) - Handle HTTP 429 rate limits with Retry-After header support - Retry on 5xx server errors, fail fast on 4xx client errors - Add dead-letter logging and metrics for exhausted retries - Wrap all Asana write operations with retry decorator
- Add environment variables: GITHUB_WEBHOOK_SECRET, ASANA_PAT, ASANA_WORKSPACE_GID, ASANA_PROJECT_GID - Register webhook router in FastAPI app - Configure Docker Compose for local development - Add Terraform variables and Kubernetes secrets for deployment
- Add asana>=5.2.2 for Asana API client - Add httpx>=0.28.1 for async HTTP requests - Add tenacity>=8.2.3 for retry logic with exponential backoff
- Exclude test_webhook_*.sh scripts - Exclude WEBHOOK_DESIGN.md and PHASE*.md documentation files
- Update docstring to document all supported PR actions - Add try/except for JSON parsing errors - Wrap pull_request handler in try/except to prevent 500s - Return structured dead-letter response on unexpected errors - Add metrics for dead-letter webhook errors
- Move _resolve_assignee to top-level imports (remove inline imports) - Update docstring to reflect all supported PR actions - Improve code clarity and maintainability
- Add ASANA_RETRY_MAX_ATTEMPTS, ASANA_RETRY_INITIAL_DELAY_MS, ASANA_RETRY_MAX_DELAY_MS to config - Update all retry_with_backoff calls to use config values - Enable runtime tuning of retry behavior without code changes
- Document all emitted metrics with descriptions - Clarify difference between sync.latency_ms and webhook.latency_ms - Improve observability documentation for dashboards
- Add comment about regex robustness in PR description updates - Fix import order in retry.py (move asyncio to top) - Remove unused time import
- Add requests>=2.31.0 to dependencies - Required for _get_github_to_asana_mapping function - Prevents ImportError that causes mapping failures
- remove tasks_created increment (already done in pr_handler) - remove assign_updates increment (already done in pr_handler) - remove tasks_completed/tasks_reopened increments (already done in pr_handler)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| def _update_assignee(): | ||
| tasks_api.update_task({"data": task_data}, task_gid, {}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix argument order when updating task assignee
In update_task_assignee the call to TasksApi.update_task passes the request body first and the task GID second (update_task({"data": task_data}, task_gid, {})), but the Asana client expects update_task(task_gid, body, opts). This argument reversal raises a TypeError before any HTTP call is made, so every assigned/unassigned/edited webhook exhausts retries and dead-letters instead of updating the task assignee.
Useful? React with 👍 / 👎.
| def _update_completed(): | ||
| tasks_api.update_task({"data": task_data}, task_gid, {}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct update_task invocation for completion status
Similarly in update_task_completed the call tasks_api.update_task({"data": task_data}, task_gid, {}) supplies the payload before the task GID, which does not match the Asana client signature (task_gid first). This causes completion/reopen webhook actions to fail locally with argument errors and eventually dead-letter after retries, leaving Asana tasks never marked completed or reopened.
Useful? React with 👍 / 👎.
Asana Task