Skip to content

[WIP] add new cookbook for codex-jira #1910

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

Merged
merged 3 commits into from
Jun 26, 2025
Merged
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
Binary file added examples/codex/images/add_label.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/codex/images/codex_action.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/codex/images/jira_comment.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/codex/images/jira_rule.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/codex/images/jira_status_change.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
315 changes: 315 additions & 0 deletions examples/codex/jira-github.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,315 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"vscode": {
"languageId": "raw"
}
},
"source": [
"# Automate Jira ↔ GitHub with `codex-cli`\n",
"\n",
"## Purpose of this cookbook\n",
"\n",
"This cookbook provides a practical, step-by-step approach to automating the workflow between Jira and GitHub. By labeling a Jira issue, you trigger an end-to-end process that creates a **GitHub pull request**, keeps both systems updated, and streamlines code review, all with minimal manual effort. The automation is powered by the [`codex-cli`](https://github.com/openai/openai-codex) agent running inside a GitHub Action.\n",
"\n",
"# <img src=\"./images/codex_action.png\" alt=\"Full data-flow diagram\" width=\"500\"/>\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"vscode": {
"languageId": "raw"
}
},
"source": [
"The flow is:\n",
"\n",
"1. Label a Jira issue \n",
"2. Jira Automation calls the GitHub Action \n",
"3. The action spins up `codex-cli` to implement the change \n",
"4. A PR is opened\n",
"5. Jira is transitioned & annotated - creating a neat, zero-click loop. This includes changing the status of the ticket, adding the PR link and commenting in the ticket with updates.\n",
"\n",
"## Prerequisites\n",
"\n",
"* Jira: project admin rights + ability to create automation rules \n",
"* GitHub: write access, permission to add repository secrets, and a protected `main` branch \n",
"* API keys & secrets placed as repository secrets:\n",
" * `OPENAI_API_KEY` – your OpenAI key for `codex-cli` \n",
" * `JIRA_BASE_URL`, `JIRA_EMAIL`, `JIRA_API_TOKEN` – for REST calls from the action \n",
"* `codex-cli` installed locally (`pnpm add -g @openai/codex`) for ad-hoc testing \n",
"* A repository that contains a `.github/workflows/` folder\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"vscode": {
"languageId": "raw"
}
},
"source": [
"## Create the Jira Automation Rule\n",
"\n",
"<img src=\"./images/jira_rule.png\" alt=\"Automation Rule\" width=\"500\"/>\n",
"\n",
"The first step in this rule listens for changes to an issue’s labels. This ensures we only trigger the automation when a label is added or modified—no need to process every update to the issue.\n",
"\n",
"Next, we check whether the updated labels include a specific keyword, in our example we are using `aswe`. This acts as a filter so that only issues explicitly tagged for automation proceed, avoiding unnecessary noise from unrelated updates.\n",
"\n",
"If the condition is met, we send a `POST` request to GitHub’s `workflow_dispatch` endpoint. This kicks off a GitHub Actions workflow with the relevant issue context. We pass in the issue key, summary, and a cleaned-up version of the description—escaping quotes and newlines so the payload parses correctly in YAML/JSON. There are [additional fields](https://support.atlassian.com/cloud-automation/docs/jira-smart-values-issues/) available as variables in JIRA to give the codex agent more context during its execution.\n",
"\n",
"This setup allows teams to tightly control which Jira issues trigger automation, and ensures GitHub receives structured, clean metadata to act on. We can also set up multiple labels, each triggering a different GitHub Action. For example, one label could kick off a quick bug fix workflow, while another might start work on refactoring code or generating API stubs.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"vscode": {
"languageId": "raw"
}
},
"source": [
"## Add the GitHub Action\n",
"\n",
"GitHub Actions enable you to automate workflows within your GitHub repository by defining them in YAML files. These workflows specify a series of jobs and steps to execute. When triggered either manually or via a POST request, GitHub automatically provisions the necessary environment and runs the defined workflow steps.\n",
"\n",
"To process the `POST` request from JIRA we will create a Github action with a YAML like below in the `.github/workflows/` directory of the repository:\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```yaml\n",
"name: Codex Automated PR\n",
"on:\n",
" workflow_dispatch:\n",
" inputs:\n",
" issue_key:\n",
" description: 'JIRA issue key (e.g., PROJ-123)'\n",
" required: true\n",
" issue_summary:\n",
" description: 'Brief summary of the issue'\n",
" required: true\n",
" issue_description:\n",
" description: 'Detailed issue description'\n",
" required: true\n",
"\n",
"permissions:\n",
" contents: write # allow the action to push code & open the PR\n",
" pull-requests: write # allow the action to create and update PRs\n",
"\n",
"jobs:\n",
" codex_auto_pr:\n",
" runs-on: ubuntu-latest\n",
"\n",
" steps:\n",
" # 0 – Checkout repository\n",
" - uses: actions/checkout@v4\n",
" with:\n",
" fetch-depth: 0 # full history → lets Codex run tests / git blame if needed\n",
"\n",
" # 1 – Set up Node.js and Codex\n",
" - uses: actions/setup-node@v4\n",
" with:\n",
" node-version: 22\n",
" - run: pnpm add -g @openai/codex\n",
"\n",
" # 2 – Export / clean inputs (available via $GITHUB_ENV)\n",
" - id: vars\n",
" run: |\n",
" echo \"ISSUE_KEY=${{ github.event.inputs.issue_key }}\" >> $GITHUB_ENV\n",
" echo \"TITLE=${{ github.event.inputs.issue_summary }}\" >> $GITHUB_ENV\n",
" echo \"RAW_DESC=${{ github.event.inputs.issue_description }}\" >> $GITHUB_ENV\n",
" DESC_CLEANED=$(echo \"${{ github.event.inputs.issue_description }}\" | tr '\\n' ' ' | sed 's/\"/'\\''/g')\n",
" echo \"DESC=$DESC_CLEANED\" >> $GITHUB_ENV\n",
" echo \"BRANCH=codex/${{ github.event.inputs.issue_key }}\" >> $GITHUB_ENV\n",
"\n",
" # 3 – Transition Jira issue to \"In Progress\"\n",
" - name: Jira – Transition to In Progress\n",
" env:\n",
" ISSUE_KEY: ${{ env.ISSUE_KEY }}\n",
" JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }}\n",
" JIRA_EMAIL: ${{ secrets.JIRA_EMAIL }}\n",
" JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}\n",
" run: |\n",
" curl -sS -X POST \\\n",
" --url \"$JIRA_BASE_URL/rest/api/3/issue/$ISSUE_KEY/transitions\" \\\n",
" --user \"$JIRA_EMAIL:$JIRA_API_TOKEN\" \\\n",
" --header 'Content-Type: application/json' \\\n",
" --data '{\"transition\":{\"id\":\"21\"}}'\n",
Copy link
Contributor

Choose a reason for hiding this comment

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

Should transition ID be a dynamic value?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The transition ID apparently varies by project. https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issues/#api-rest-api-3-issue-issueidorkey-transitions-get I added a link to the doc in my new commit

" # 21 is the transition ID for changing the ticket status to In Progress. Learn more here: https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issues/#api-rest-api-3-issue-issueidorkey-transitions-get\n",
"\n",
" # 4 – Set Git author for CI commits\n",
" - run: |\n",
" git config user.email \"github-actions[bot]@users.noreply.github.com\"\n",
" git config user.name \"github-actions[bot]\"\n",
"\n",
" # 5 – Let Codex implement & commit (no push yet)\n",
" - name: Codex implement & commit\n",
" env:\n",
" OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}\n",
" CODEX_QUIET_MODE: \"1\" # suppress chatty logs\n",
" run: |\n",
" set -e\n",
" codex --approval-mode full-auto --no-terminal --quiet \\\n",
" \"Implement JIRA ticket $ISSUE_KEY: $TITLE. $DESC\"\n",
"\n",
" git add -A\n",
" git commit -m \"feat($ISSUE_KEY): $TITLE\"\n",
"\n",
" # 6 – Open (and push) the PR in one go\n",
" - id: cpr\n",
" uses: peter-evans/create-pull-request@v6\n",
" with:\n",
" token: ${{ secrets.GITHUB_TOKEN }}\n",
" base: main\n",
" branch: ${{ env.BRANCH }}\n",
" title: \"${{ env.TITLE }} (${{ env.ISSUE_KEY }})\"\n",
" body: |\n",
" Auto-generated by Codex for JIRA **${{ env.ISSUE_KEY }}**.\n",
" ---\n",
" ${{ env.DESC }}\n",
"\n",
" # 7 – Transition Jira to \"In Review\" & drop the PR link\n",
" - name: Jira – Transition to In Review & Comment PR link\n",
" env:\n",
" ISSUE_KEY: ${{ env.ISSUE_KEY }}\n",
" JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }}\n",
" JIRA_EMAIL: ${{ secrets.JIRA_EMAIL }}\n",
" JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}\n",
" PR_URL: ${{ steps.cpr.outputs.pull-request-url }}\n",
" run: |\n",
" # Status transition\n",
" curl -sS -X POST \\\n",
" --url \"$JIRA_BASE_URL/rest/api/3/issue/$ISSUE_KEY/transitions\" \\\n",
" --user \"$JIRA_EMAIL:$JIRA_API_TOKEN\" \\\n",
" --header 'Content-Type: application/json' \\\n",
" --data '{\"transition\":{\"id\":\"31\"}}'\n",
" # 31 is the Transition ID for changing the ticket status to In Review. Learn more here: https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issues/#api-rest-api-3-issue-issueidorkey-transitions-get\n",
"\n",
" # Comment with PR link\n",
" curl -sS -X POST \\\n",
" --url \"$JIRA_BASE_URL/rest/api/3/issue/$ISSUE_KEY/comment\" \\\n",
" --user \"$JIRA_EMAIL:$JIRA_API_TOKEN\" \\\n",
" --header 'Content-Type: application/json' \\\n",
" --data \"{\\\"body\\\":{\\\"type\\\":\\\"doc\\\",\\\"version\\\":1,\\\"content\\\":[{\\\"type\\\":\\\"paragraph\\\",\\\"content\\\":[{\\\"type\\\":\\\"text\\\",\\\"text\\\":\\\"PR created: $PR_URL\\\"}]}]}}\"\n",
"```\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"vscode": {
"languageId": "raw"
}
},
"source": [
"## Key Steps in the Workflow\n",
"\n",
"1. **Codex Implementation & Commit** (Step 5)\n",
" - Uses OpenAI API to implement the JIRA ticket requirements\n",
" - Runs codex CLI in full-auto mode without terminal interaction\n",
" - Commits all changes with standardized commit message\n",
"\n",
"2. **Create Pull Request** (Step 6) \n",
" - Uses peter-evans/create-pull-request action\n",
" - Creates PR against main branch\n",
" - Sets PR title and description from JIRA ticket info\n",
" - Returns PR URL for later use\n",
"\n",
"3. **JIRA Updates** (Step 7)\n",
" - Transitions ticket to \"In Review\" status via JIRA API\n",
" - Posts comment with PR URL on the JIRA ticket\n",
" - Uses curl commands to interact with JIRA REST API\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"vscode": {
"languageId": "raw"
}
},
"source": [
"## Label an Issue\n",
"\n",
"Attach the special `aswe` label to any bug/feature ticket:\n",
"\n",
"1. **During creation** – add it in the \"Labels\" field before hitting *Create* \n",
"2. **Existing issue** – hover the label area → click the pencil icon → type `aswe`\n",
"\n",
"<img src=\"./images/add_label.png\" alt=\"Adding a label\" width=\"500\"/>\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"vscode": {
"languageId": "raw"
}
},
"source": [
"## End-to-end Flow\n",
"\n",
"1. Jira label added → Automation triggers\n",
"2. `workflow_dispatch` fires; action spins up on GitHub\n",
"3. `codex-cli` edits the codebase & commits\n",
"4. PR is opened on the generated branch\n",
"5. Jira is moved to **In Review** and a comment with the PR URL is posted\n",
"6. Reviewers are notified per your normal branch protection settings\n",
"\n",
"<img src=\"./images/jira_comment.png\" alt=\"Jira comment with PR link\" width=\"300\"/>\n",
"<img src=\"./images/jira_status_change.png\" alt=\"Jira status transition to In Review\" width=\"300\"/>\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"vscode": {
"languageId": "raw"
}
},
"source": [
"## Review & Merge the PR\n",
"\n",
"You can open the PR link posted in the JIRA ticket and check to see if everything looks good and then merge it. If you have branch protection and Smart Commits integration enabled, the Jira ticket will be automatically closed when the pull request is merged.\n",
"\n",
"## Conclusion\n",
"\n",
"This automation streamlines your development workflow by creating a seamless integration between Jira and GitHub:\n",
"\n",
"* **Automatic status tracking** - Tickets progress through your workflow without manual updates\n",
"* **Improved developer experience** - Focus on reviewing code quality instead of writing boilerplate code\n",
"* **Reduced handoff friction** - The PR is ready for review as soon as the ticket is labeled\n",
"\n",
"The `codex-cli` tool is a powerful AI coding assistant that automates repetitive programming tasks. You can explore more about it [here](https://github.com/openai/codex/)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.10"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
9 changes: 9 additions & 0 deletions registry.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@
# This file is used to generate cookbook.openai.com. It specifies which paths we
# should build pages for, and indicates metadata such as tags, creation date and
# authors for each page.
- title: Automate Jira ↔ GitHub with Codex
path: examples/codex/jira-github.ipynb
date: 2025-06-21
authors:
- alwell-kevin
- narenoai
tags:
- codex
- automation

- title: Fine-Tuning Techniques - Choosing Between SFT, DPO, and RFT (With a Guide to DPO)
path: examples/Fine_tuning_direct_preference_optimization_guide.ipynb
Expand Down