-
Notifications
You must be signed in to change notification settings - Fork 7
feat: add edge-scrum Jira config-as-code with CI automation #14
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
Draft
jeff-roche
wants to merge
1
commit into
openshift-eng:main
Choose a base branch
from
jeff-roche:feat/edge-scrum-jira-config
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| name: Jira Config — Apply Changes | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
| paths: | ||
| - 'edge-scrum/.jira-config/**' | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| concurrency: | ||
| group: jira-sync-apply | ||
| cancel-in-progress: false | ||
|
|
||
| jobs: | ||
| validate-configs: | ||
| name: Validate JSON config schemas | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Install check-jsonschema | ||
| run: pip install check-jsonschema | ||
|
|
||
| - name: Validate .jira-config JSON files | ||
| run: edge-scrum/.ci/scripts/validate-configs.sh | ||
|
|
||
| apply: | ||
| name: Apply Jira config changes | ||
| needs: validate-configs | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - name: Apply metadata changes to Jira | ||
| run: edge-scrum/.ci/scripts/apply-changes.sh | ||
| env: | ||
| JIRA_USERNAME: ${{ secrets.JIRA_USERNAME }} | ||
| JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} | ||
| GIT_BASE_SHA: ${{ github.event.before }} | ||
| SYNC_ALL: ${{ github.event_name == 'workflow_dispatch' }} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| name: Jira Config — PR Validation | ||
|
|
||
| on: | ||
| pull_request: | ||
| branches: [main] | ||
| paths: | ||
| - 'edge-scrum/.jira-config/**' | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| validate-configs: | ||
| name: Validate JSON config schemas | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Install check-jsonschema | ||
| run: pip install check-jsonschema | ||
|
|
||
| - name: Validate .jira-config JSON files | ||
| run: edge-scrum/.ci/scripts/validate-configs.sh | ||
|
|
||
| validate-readme: | ||
| name: Validate README sync | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - name: Validate README updated alongside config changes | ||
| run: edge-scrum/.ci/scripts/validate-readme-sync.sh | ||
|
|
||
| dry-run: | ||
| name: Dry-run Jira sync | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - name: Preview changes | ||
| run: edge-scrum/.ci/scripts/apply-changes.sh --dry-run | ||
| env: | ||
| JIRA_USERNAME: ${{ secrets.JIRA_USERNAME }} | ||
| JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| .env | ||
| **/.env |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,151 @@ | ||
| # CI Scripts | ||
|
|
||
| This directory contains CI/CD validation and sync scripts for the edge-scrum project. | ||
|
|
||
| ## Validation Scripts | ||
|
|
||
| ### validate-readme-sync.sh | ||
|
|
||
| Validates that changes to metadata JSON files in `.jira-config/` are reflected in the README. | ||
|
|
||
| **Purpose:** Ensures documentation stays in sync with configuration changes. | ||
|
|
||
| **Usage:** | ||
|
|
||
| ```bash | ||
| # Run locally | ||
| .ci/scripts/validate-readme-sync.sh | ||
|
|
||
| # In GitHub Actions | ||
| - name: Validate README sync | ||
| run: ./edge-scrum/.ci/scripts/validate-readme-sync.sh | ||
| ``` | ||
|
|
||
| **Behavior:** | ||
|
|
||
| - Detects modifications to any of the following files: | ||
| - `boards.json` | ||
| - `filters.json` | ||
| - `projects.json` | ||
| - `components.json` | ||
| - `plans.json` | ||
| - `labels.json` | ||
| - If any metadata file changed, verifies that `README.md` was also updated | ||
| - Exits with error code 1 if README wasn't updated alongside metadata changes | ||
| - Exits with code 0 if no metadata changed or if both metadata and README changed | ||
|
|
||
| **Environment Variables:** | ||
|
|
||
| - `GITHUB_BASE_REF` - GitHub Actions PR base branch (auto-detected) | ||
| - `CI_MERGE_REQUEST_TARGET_BRANCH_NAME` - GitLab CI target branch (auto-detected) | ||
| - Falls back to comparing against `origin/main` for local development | ||
|
|
||
| ## Sync Scripts | ||
|
|
||
| These scripts apply metadata changes from JSON files to Jira via REST API. | ||
|
|
||
| ### apply-changes.sh | ||
|
|
||
| **Orchestration script** that detects changed metadata files and applies them to Jira. | ||
|
|
||
| **Purpose:** Main entry point for syncing metadata changes to Jira. | ||
|
|
||
| **Usage:** | ||
|
|
||
| ```bash | ||
| # Dry run (preview changes) | ||
| .ci/scripts/apply-changes.sh --dry-run | ||
|
|
||
| # Apply changes | ||
| .ci/scripts/apply-changes.sh | ||
|
|
||
| # In GitHub Actions | ||
| - name: Apply metadata changes to Jira | ||
| run: ./edge-scrum/.ci/scripts/apply-changes.sh | ||
| env: | ||
| JIRA_URL: ${{ secrets.JIRA_URL }} | ||
| JIRA_USERNAME: ${{ secrets.JIRA_USERNAME }} | ||
| JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} | ||
| ``` | ||
|
|
||
| **Behavior:** | ||
|
|
||
| - Detects which metadata files changed (boards.json, filters.json, projects.json, components.json) | ||
| - Calls the appropriate sync script for each changed file | ||
| - Passes `--dry-run` flag to all sync scripts if provided | ||
| - Exits with code 1 if any sync script fails | ||
| - Skips `labels.json` (no formal API) | ||
|
|
||
| ### sync-boards.sh | ||
|
|
||
| Updates board properties in Jira. | ||
|
|
||
| **API:** `PUT /rest/agile/1.0/board/{boardId}/properties/{propertyKey}` | ||
|
|
||
| **Updates:** Board properties (e.g., roadmaps features, child issue planning) | ||
|
|
||
| **Note:** Only properties can be updated via API. Structural configuration (columns, estimation, ranking) requires Jira UI. | ||
|
|
||
| ### sync-filters.sh | ||
|
|
||
| Updates filter metadata, JQL, and permissions in Jira. | ||
|
|
||
| **API:** `PUT /rest/api/2/filter/{filterId}` | ||
|
|
||
| **Updates:** Filter name, description, JQL, edit permissions, share permissions | ||
|
|
||
| **Note:** Filter ownership transfers require Jira UI. | ||
|
|
||
| ### sync-projects.sh | ||
|
|
||
| Updates project metadata in Jira. | ||
|
|
||
| **API:** `PUT /rest/api/2/project/{projectKey}` | ||
|
|
||
| **Updates:** Project name, description, lead, assigneeType | ||
|
|
||
| **Note:** Role configuration is listed in JSON but is UI-only (cannot be updated via API). | ||
|
|
||
| ### sync-components.sh | ||
|
|
||
| Updates component metadata in Jira. | ||
|
|
||
| **API:** `PUT /rest/api/2/component/{componentId}` | ||
|
|
||
| **Updates:** Component name, description | ||
|
|
||
| **Note:** Only updates components with `component_id` in the JSON. Entries without `component_id` must be created manually. | ||
|
|
||
| ## Common Features | ||
|
|
||
| All sync scripts share these features: | ||
|
|
||
| - **`--dry-run` flag:** Preview changes without applying them | ||
| - **Credentials:** Load from `edge-scrum/.env` (JIRA_URL, JIRA_USERNAME, JIRA_API_TOKEN) | ||
| - **Error handling:** Exit with code 1 if any updates fail | ||
| - **Validation:** Check prerequisites (jq, curl, config files, env vars) | ||
| - **Logging:** Clear, color-coded output showing what's being updated | ||
| - **Safety:** Only update existing entities (no create/delete operations) | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| ```bash | ||
| # Install dependencies | ||
| sudo dnf install jq curl git # Fedora/RHEL | ||
| sudo apt install jq curl git # Debian/Ubuntu | ||
|
|
||
| # Configure credentials | ||
| cat > edge-scrum/.env <<EOF | ||
| export JIRA_URL="https://redhat.atlassian.net" | ||
| export JIRA_USERNAME="your-email@redhat.com" | ||
| export JIRA_API_TOKEN="your-api-token" | ||
| EOF | ||
| ``` | ||
|
|
||
| ## Workflow | ||
|
|
||
| 1. **Make changes** to metadata JSON files in `.jira-config/` | ||
| 2. **Update README.md** with the changes (validated by `validate-readme-sync.sh`) | ||
| 3. **Preview changes** with `apply-changes.sh --dry-run` | ||
| 4. **Apply changes** with `apply-changes.sh` | ||
| 5. **Commit and push** to create a PR | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| { | ||
| "$schema": "http://json-schema.org/draft-07/schema#", | ||
| "type": "object", | ||
| "required": ["boards"], | ||
| "additionalProperties": false, | ||
| "properties": { | ||
| "boards": { | ||
| "type": "array", | ||
| "minItems": 1, | ||
| "items": { | ||
| "type": "object", | ||
| "required": ["id", "name", "type", "filter_id", "properties"], | ||
| "additionalProperties": false, | ||
| "properties": { | ||
| "id": { | ||
| "type": "string", | ||
| "pattern": "^[0-9]+$" | ||
| }, | ||
| "name": { | ||
| "type": "string", | ||
| "minLength": 1 | ||
| }, | ||
| "type": { | ||
| "type": "string", | ||
| "enum": ["scrum", "kanban"] | ||
| }, | ||
| "filter_id": { | ||
| "type": "string", | ||
| "pattern": "^[0-9]+$" | ||
| }, | ||
| "properties": { | ||
| "type": "object", | ||
| "additionalProperties": { | ||
| "type": "boolean" | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| { | ||
| "$schema": "http://json-schema.org/draft-07/schema#", | ||
| "type": "object", | ||
| "required": ["components"], | ||
| "additionalProperties": false, | ||
| "properties": { | ||
| "components": { | ||
| "type": "array", | ||
| "minItems": 1, | ||
| "items": { | ||
| "type": "object", | ||
| "required": ["name", "description", "projects"], | ||
| "additionalProperties": false, | ||
| "properties": { | ||
| "name": { | ||
| "type": "string", | ||
| "minLength": 1 | ||
| }, | ||
| "description": { | ||
| "type": "string" | ||
| }, | ||
| "projects": { | ||
| "type": "array", | ||
| "minItems": 1, | ||
| "items": { | ||
| "type": "object", | ||
| "required": ["project_id", "project_key"], | ||
| "additionalProperties": false, | ||
| "properties": { | ||
| "project_id": { | ||
| "type": "string", | ||
| "pattern": "^[0-9]+$" | ||
| }, | ||
| "project_key": { | ||
| "type": "string", | ||
| "minLength": 1 | ||
| }, | ||
| "component_id": { | ||
| "type": "string", | ||
| "pattern": "^[0-9]+$" | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Credential setup docs are inconsistent with script behavior and PR security model.
At Line 124 and Line 138-Line 142, the README says credentials are loaded from
.env, but these scripts read process environment variables and do not source that file. This can mislead contributors and conflicts with the env-only secret handling described in this PR.📝 Suggested documentation correction
🤖 Prompt for AI Agents