@aliaksandarpratashchyk/kickcat 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json ADDED
@@ -0,0 +1,91 @@
1
+ {
2
+ "name": "@aliaksandarpratashchyk/kickcat",
3
+ "version": "0.5.0",
4
+ "description": "Infrastructure-as-code toolkit for GitHub repository automation. Includes reusable workflows, utilities, and a CLI to install workflow templates.",
5
+ "bin": {
6
+ "kickcat": "./dist/bundle.js"
7
+ },
8
+ "author": "Aliaksandar Pratashchyk <aliaksandarpratashchyk@gmail.com>",
9
+ "license": "MIT",
10
+ "keywords": [
11
+ "github-actions",
12
+ "workflows",
13
+ "automation",
14
+ "iac",
15
+ "cli",
16
+ "milestones",
17
+ "labels",
18
+ "projects",
19
+ "github",
20
+ "ci"
21
+ ],
22
+ "files": [
23
+ "dist",
24
+ "templates",
25
+ "schemas",
26
+ "LICENSE",
27
+ "README.md"
28
+ ],
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "git+https://github.com/aliaksandarpratashchyk/kickcat.git"
32
+ },
33
+ "bugs": {
34
+ "url": "https://github.com/aliaksandarpratashchyk/kickcat/issues"
35
+ },
36
+ "homepage": "https://github.com/aliaksandarpratashchyk/kickcat#readme",
37
+ "scripts": {
38
+ "build": "webpack",
39
+ "e2e": "npm run build && jest --testPathIgnorePatterns src",
40
+ "test": "jest --testPathIgnorePatterns e2e > COVERAGE.md && coverage-badges-cli -s ./coverage/coverage-summary.json -o ./coverage.svg --label Coverage",
41
+ "format": "npx prettier . --write",
42
+ "lint": "cross-env ESLINT_ENV=cli npx eslint . --fix"
43
+ },
44
+ "devDependencies": {
45
+ "@eslint/js": "^9.39.0",
46
+ "@octokit/core": "^7.0.6",
47
+ "@octokit/types": "^16.0.0",
48
+ "@types/jest": "^30.0.0",
49
+ "@types/node": "^24.6.2",
50
+ "@types/underscore": "^1.13.0",
51
+ "coverage-badges-cli": "^2.2.0",
52
+ "cpx": "^1.2.1",
53
+ "cross-env": "^10.1.0",
54
+ "eslint": "^9.39.0",
55
+ "eslint-config-prettier": "^10.1.8",
56
+ "eslint-import-resolver-typescript": "^4.4.4",
57
+ "eslint-plugin-import-x": "^4.16.1",
58
+ "eslint-plugin-jest": "^29.0.1",
59
+ "eslint-plugin-perfectionist": "^4.15.1",
60
+ "fork-ts-checker-webpack-plugin": "^9.1.0",
61
+ "jest": "^30.1.3",
62
+ "memfs": "^4.51.0",
63
+ "prettier": "3.6.2",
64
+ "rimraf": "^6.1.0",
65
+ "terser-webpack-plugin": "^5.3.14",
66
+ "ts-jest": "^29.4.4",
67
+ "ts-loader": "^9.5.4",
68
+ "ts-node": "^10.9.2",
69
+ "typescript": "^5.9.2",
70
+ "typescript-eslint": "^8.46.2",
71
+ "webpack": "^5.102.1",
72
+ "webpack-cli": "^6.0.1"
73
+ },
74
+ "dependencies": {
75
+ "@actions/core": "^1.10.1",
76
+ "@actions/github": "^6.0.0",
77
+ "@octokit/plugin-paginate-graphql": "^6.0.0",
78
+ "@octokit/plugin-paginate-rest": "^14.0.0",
79
+ "@octokit/plugin-rest-endpoint-methods": "^17.0.0",
80
+ "@octokit/rest": "^22.0.1",
81
+ "@types/js-yaml": "^4.0.9",
82
+ "ajv": "^8.17.1",
83
+ "commander": "^12.1.0",
84
+ "dotenv": "^17.2.3",
85
+ "octokit": "^5.0.5",
86
+ "reflect-metadata": "^0.2.2",
87
+ "tsyringe": "^4.10.0",
88
+ "underscore": "^1.13.7",
89
+ "yaml": "^2.4.1"
90
+ }
91
+ }
@@ -0,0 +1,165 @@
1
+ $schema: 'http://json-schema.org/draft-07/schema#'
2
+ title: 'GitHub Issue Schema'
3
+ type: object
4
+ required:
5
+ - title
6
+ additionalProperties: false
7
+
8
+ properties:
9
+ number:
10
+ order: 1
11
+ type: number
12
+ doNotSuggest: true
13
+ description: 'GitHub issue number assigned automatically.'
14
+ markdownDescription: |
15
+ **Internal GitHub issue number.**
16
+
17
+ - Added after first sync
18
+ - Used for linking & referencing
19
+ - Do not modify manually
20
+ x-kickcat-unique: true
21
+ x-kickcat-primary-key: true
22
+
23
+ title:
24
+ order: 2
25
+ type: string
26
+ description: 'Issue title.'
27
+ markdownDescription: |
28
+ **Issue title.**
29
+
30
+ Short, clear, and descriptive.
31
+
32
+ Example:
33
+ ```yaml
34
+ title: "Implement milestone synchronization"
35
+ ```
36
+ x-kickcat-new-unique: true
37
+
38
+ milestone:
39
+ order: 3
40
+ description: 'Milestone reference (number or key/title).'
41
+ markdownDescription: |
42
+ **Milestone reference for this issue.**
43
+
44
+ Accepts either:
45
+ - A **number** — GitHub milestone number
46
+ - A **string** — milestone key or title
47
+
48
+ Examples:
49
+ ```yaml
50
+ milestone: 3 # GitHub milestone #3
51
+ milestone: "[Seed] Milestone 1 – Setup"
52
+ milestone: "seed-1"
53
+ ```
54
+ oneOf:
55
+ - type: number
56
+ - type: string
57
+ x-kickcat-reference: milestone
58
+
59
+ labels:
60
+ order: 4
61
+ type: array
62
+ description: 'List of GitHub label names.'
63
+ markdownDescription: |
64
+ **Labels assigned to the issue.**
65
+
66
+ Must match defined labels in your label schema/files.
67
+
68
+ Example:
69
+ ```yaml
70
+ labels:
71
+ - "priority:high"
72
+ - "type:feature"
73
+ ```
74
+ items:
75
+ type: string
76
+ default: []
77
+ x-kickcat-reference: label
78
+
79
+ dependencies:
80
+ order: 5
81
+ type: array
82
+ description: 'List of dependent issues (string or number).'
83
+ markdownDescription: |
84
+ **Dependencies for this issue.**
85
+
86
+ Accepts:
87
+ - Issue numbers
88
+ - Issue aliases (strings)
89
+
90
+ Examples:
91
+ ```yaml
92
+ dependencies:
93
+ - 12
94
+ - "issue-init"
95
+ ```
96
+ items:
97
+ oneOf:
98
+ - type: number
99
+ - type: string
100
+ default: []
101
+ x-kickcat-reference: issue
102
+
103
+ state:
104
+ order: 6
105
+ type: string
106
+ description: 'Issue state: open or closed.'
107
+ markdownDescription: |
108
+ **GitHub Issue State.**
109
+
110
+ Represents whether the issue is currently **open** or **closed**.
111
+
112
+ Allowed values:
113
+ - `open`
114
+ - `closed`
115
+
116
+ Matches GitHub API behavior (IssueState enum).
117
+ enum:
118
+ - open
119
+ - closed
120
+ enumDescriptions:
121
+ - 'Open issue'
122
+ - 'Closed issue'
123
+
124
+ markdownEnumDescriptions:
125
+ - |
126
+ **Open issue.**
127
+ Active and not yet completed.
128
+ - |
129
+ **Closed issue.**
130
+ Finished or archived.
131
+
132
+ description:
133
+ order: 8
134
+ type: string
135
+ format: textarea
136
+ description: 'Full issue description.'
137
+ markdownDescription: |
138
+ **Full issue description (Markdown supported).**
139
+
140
+ Supports:
141
+ - paragraphs
142
+ - lists
143
+ - code blocks
144
+ - task lists
145
+
146
+ Example:
147
+ ```md
148
+ ### Goal
149
+ Implement milestone sync.
150
+
151
+ ### Steps
152
+ - [ ] Parse YAML
153
+ - [ ] Compare with GitHub
154
+ - [ ] Update changed fields
155
+ ```
156
+
157
+ defaultSnippets:
158
+ - label: 'Issue Template'
159
+ description: 'Insert a standard issue structure.'
160
+ body:
161
+ title: '$1'
162
+ milestone: '$2'
163
+ labels: []
164
+ dependencies: []
165
+ description: '$3'
@@ -0,0 +1,68 @@
1
+ $schema: 'http://json-schema.org/draft-07/schema#'
2
+ title: 'GitHub Label Schema'
3
+ type: object
4
+ required:
5
+ - name
6
+ - color
7
+ additionalProperties: false
8
+
9
+ properties:
10
+ name:
11
+ order: 1
12
+ type: string
13
+ description: 'Label name as it appears on GitHub.'
14
+ markdownDescription: |
15
+ **Label name** displayed on GitHub.
16
+
17
+ Examples:
18
+ - `priority:high`
19
+ - `type:feature`
20
+ - `scope:core`
21
+
22
+ This name must be **unique** per repository.
23
+ x-kickcat-unique: true
24
+ x-kickcat-primary-key: true
25
+
26
+ color:
27
+ order: 2
28
+ type: string
29
+ pattern: '^[0-9a-fA-F]{6}$'
30
+ description: 'Hex color (6 characters, without #).'
31
+ markdownDescription: |
32
+ **Label color in hex format**.
33
+
34
+ Must be a 6-character hex code:
35
+ - lowercase or uppercase
36
+ - must **not** include `#`
37
+
38
+ Examples:
39
+ ```yaml
40
+ color: "d73a4a" # red
41
+ color: "1d76db" # blue
42
+ color: "0e8a16" # green
43
+ ```
44
+
45
+ description:
46
+ order: 3
47
+ type: string
48
+ format: textarea
49
+ description: 'Full label description.'
50
+ markdownDescription: |
51
+ **Full description of the label.**
52
+
53
+ This appears on GitHub when hovering over the label.
54
+ Supports Markdown formatting.
55
+
56
+ Example:
57
+ ```md
58
+ Must be fixed as soon as possible.
59
+ Blocks releases.
60
+ ```
61
+
62
+ defaultSnippets:
63
+ - label: 'Label Template'
64
+ description: 'Insert a standard GitHub label structure.'
65
+ body:
66
+ name: '$1'
67
+ color: '$2'
68
+ description: '$3'
@@ -0,0 +1,109 @@
1
+ $schema: 'http://json-schema.org/draft-07/schema#'
2
+ title: 'GitHub Milestone Schema'
3
+ type: object
4
+ required:
5
+ - title
6
+ additionalProperties: false
7
+
8
+ properties:
9
+ number:
10
+ doNotSuggest: true
11
+ order: 1
12
+ type: integer
13
+ description: 'GitHub milestone number assigned by GitHub.'
14
+ markdownDescription: |
15
+ **Internal GitHub milestone number.**
16
+
17
+ - Automatically added after creation
18
+ - Used as a stable reference for updates
19
+ - Do not edit manually
20
+ x-kickcat-unique: true
21
+ x-kickcat-primary-key: true
22
+
23
+ title:
24
+ order: 2
25
+ type: string
26
+ description: 'Milestone title.'
27
+ markdownDescription: |
28
+ **Milestone title shown on GitHub.**
29
+
30
+ Tip: Titles often include a key prefix in square brackets,
31
+ e.g. `[Seed] Milestone 1 – Preparation`.
32
+
33
+ This acts as the *unique key* for matching milestones between
34
+ YAML files and GitHub during syncing.
35
+ x-kickcat-unique: true
36
+
37
+ dueDate:
38
+ order: 3
39
+ type: string
40
+ format: date
41
+ description: 'Due date in YYYY-MM-DD.'
42
+ markdownDescription: |
43
+ **Optional milestone due date.**
44
+
45
+ Use ISO format: `YYYY-MM-DD`.
46
+
47
+ Example:
48
+ ```yaml
49
+ dueDate: "2025-05-17"
50
+ ```
51
+
52
+ state:
53
+ order: 4
54
+ type: string
55
+ enum:
56
+ - open
57
+ - closed
58
+ description: 'Milestone state.'
59
+ markdownDescription: |
60
+ **Milestone state.**
61
+
62
+ - `open` – displayed as active on GitHub
63
+ - `closed` – milestone is finished
64
+
65
+ Your sync workflow will preserve or update this based on configuration.
66
+
67
+ enumDescriptions:
68
+ - 'Open milestone'
69
+ - 'Closed milestone'
70
+
71
+ markdownEnumDescriptions:
72
+ - |
73
+ **Open milestone.**
74
+ Active and not yet completed.
75
+ - |
76
+ **Closed milestone.**
77
+ Finished or archived.
78
+
79
+ description:
80
+ order: 5
81
+ type: string
82
+ format: textarea
83
+ description: 'Full milestone description.'
84
+ markdownDescription: |
85
+ **Full milestone description.**
86
+
87
+ Supports Markdown formatting:
88
+
89
+ - lists
90
+ - bold/italic
91
+ - links
92
+ - code blocks
93
+
94
+ Example:
95
+ ```md
96
+ ### Goal
97
+ Complete initial project setup.
98
+
99
+ ### Outcomes
100
+ - Repo ready
101
+ - CI configured
102
+ ```
103
+
104
+ defaultSnippets:
105
+ - label: 'Milestone Template'
106
+ description: 'Insert a standard milestone structure.'
107
+ body:
108
+ title: '$1'
109
+ description: '$2'
@@ -0,0 +1,72 @@
1
+ # Keep KickCat issues in sync with GitHub issue events
2
+ name: kickcat-sync-issue
3
+
4
+ on:
5
+ issues:
6
+ types: [opened, edited, reopened, closed, deleted]
7
+
8
+ permissions:
9
+ contents: write
10
+
11
+ jobs:
12
+ sync:
13
+ runs-on: ubuntu-latest
14
+ env:
15
+ KICKCAT_LOCAL_STORAGE: .github
16
+ steps:
17
+ - name: Checkout
18
+ uses: actions/checkout@v4
19
+ with:
20
+ fetch-depth: 0
21
+
22
+ - name: Setup Node.js
23
+ uses: actions/setup-node@v4
24
+ with:
25
+ node-version: 20
26
+
27
+ - name: Sync issue into repository storage
28
+ env:
29
+ ACTION: ${{ github.event.action }}
30
+ ISSUE_NUMBER: ${{ github.event.issue.number }}
31
+ run: |
32
+ set -euo pipefail
33
+
34
+ if [ -z "${ISSUE_NUMBER:-}" ]; then
35
+ echo "Issue number is missing; skipping."
36
+ exit 0
37
+ fi
38
+
39
+ case "${ACTION}" in
40
+ opened|edited|reopened|closed)
41
+ npx @aliaksandarpratashchyk/kickcat entity pull --of=issue --key=number --value="${ISSUE_NUMBER}"
42
+ ;;
43
+ deleted)
44
+ npx @aliaksandarpratashchyk/kickcat entity delete --of=issue --key=number --value="${ISSUE_NUMBER}"
45
+ ;;
46
+ *)
47
+ echo "Issue action ${ACTION} not handled; skipping."
48
+ ;;
49
+ esac
50
+
51
+ - name: Commit changes
52
+ id: commit
53
+ env:
54
+ ACTION: ${{ github.event.action }}
55
+ ISSUE_NUMBER: ${{ github.event.issue.number }}
56
+ run: |
57
+ set -euo pipefail
58
+
59
+ if git diff --quiet -- .github; then
60
+ echo "has_changes=false" >> "$GITHUB_OUTPUT"
61
+ exit 0
62
+ fi
63
+
64
+ git config user.name "github-actions[bot]"
65
+ git config user.email "github-actions[bot]@users.noreply.github.com"
66
+ git add .github
67
+ git commit -m "chore: sync issue #${ISSUE_NUMBER} (${ACTION})"
68
+ echo "has_changes=true" >> "$GITHUB_OUTPUT"
69
+
70
+ - name: Push changes
71
+ if: steps.commit.outputs.has_changes == 'true'
72
+ run: git push
@@ -0,0 +1,72 @@
1
+ # Keep KickCat labels in sync with GitHub label events
2
+ name: kickcat-sync-label
3
+
4
+ on:
5
+ label:
6
+ types: [created, edited, deleted]
7
+
8
+ permissions:
9
+ contents: write
10
+
11
+ jobs:
12
+ sync:
13
+ runs-on: ubuntu-latest
14
+ env:
15
+ KICKCAT_LOCAL_STORAGE: .github
16
+ steps:
17
+ - name: Checkout
18
+ uses: actions/checkout@v4
19
+ with:
20
+ fetch-depth: 0
21
+
22
+ - name: Setup Node.js
23
+ uses: actions/setup-node@v4
24
+ with:
25
+ node-version: 20
26
+
27
+ - name: Sync label into repository storage
28
+ env:
29
+ ACTION: ${{ github.event.action }}
30
+ LABEL_NAME: ${{ github.event.label.name }}
31
+ run: |
32
+ set -euo pipefail
33
+
34
+ if [ -z "${LABEL_NAME:-}" ]; then
35
+ echo "Label name is missing; skipping."
36
+ exit 0
37
+ fi
38
+
39
+ case "${ACTION}" in
40
+ created|edited)
41
+ npx @aliaksandarpratashchyk/kickcat entity pull --of=label --key=name --value="${LABEL_NAME}"
42
+ ;;
43
+ deleted)
44
+ npx @aliaksandarpratashchyk/kickcat entity delete --of=label --key=name --value="${LABEL_NAME}"
45
+ ;;
46
+ *)
47
+ echo "Label action ${ACTION} not handled; skipping."
48
+ ;;
49
+ esac
50
+
51
+ - name: Commit changes
52
+ id: commit
53
+ env:
54
+ ACTION: ${{ github.event.action }}
55
+ LABEL_NAME: ${{ github.event.label.name }}
56
+ run: |
57
+ set -euo pipefail
58
+
59
+ if git diff --quiet -- .github; then
60
+ echo "has_changes=false" >> "$GITHUB_OUTPUT"
61
+ exit 0
62
+ fi
63
+
64
+ git config user.name "github-actions[bot]"
65
+ git config user.email "github-actions[bot]@users.noreply.github.com"
66
+ git add .github
67
+ git commit -m "chore: sync label ${LABEL_NAME} (${ACTION})"
68
+ echo "has_changes=true" >> "$GITHUB_OUTPUT"
69
+
70
+ - name: Push changes
71
+ if: steps.commit.outputs.has_changes == 'true'
72
+ run: git push
@@ -0,0 +1,70 @@
1
+ # Keep KickCat milestones in sync with GitHub milestone events
2
+ name: kickcat-pull-milestone
3
+
4
+ on:
5
+ milestone:
6
+ types: [created, opened, edited, closed, deleted]
7
+
8
+ permissions:
9
+ contents: write
10
+
11
+ jobs:
12
+ sync:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - name: Checkout
16
+ uses: actions/checkout@v4
17
+ with:
18
+ fetch-depth: 0
19
+
20
+ - name: Setup Node.js
21
+ uses: actions/setup-node@v4
22
+ with:
23
+ node-version: 20
24
+
25
+ - name: Sync milestone into repository storage
26
+ env:
27
+ ACTION: ${{ github.event.action }}
28
+ MILESTONE_NUMBER: ${{ github.event.milestone.number }}
29
+ run: |
30
+ set -euo pipefail
31
+
32
+ if [ -z "${MILESTONE_NUMBER:-}" ]; then
33
+ echo "Milestone number is missing; skipping."
34
+ exit 0
35
+ fi
36
+
37
+ case "${ACTION}" in
38
+ created|opened|edited|closed)
39
+ npx @aliaksandarpratashchyk/kickcat entity pull --of=milestone --key=number --value="${MILESTONE_NUMBER}"
40
+ ;;
41
+ deleted)
42
+ npx @aliaksandarpratashchyk/kickcat entity delete --of=milestone --key=number --value="${MILESTONE_NUMBER}"
43
+ ;;
44
+ *)
45
+ echo "Milestone action ${ACTION} not handled; skipping."
46
+ ;;
47
+ esac
48
+
49
+ - name: Commit changes
50
+ id: commit
51
+ env:
52
+ ACTION: ${{ github.event.action }}
53
+ MILESTONE_NUMBER: ${{ github.event.milestone.number }}
54
+ run: |
55
+ set -euo pipefail
56
+
57
+ if git diff --quiet -- .github; then
58
+ echo "has_changes=false" >> "$GITHUB_OUTPUT"
59
+ exit 0
60
+ fi
61
+
62
+ git config user.name "github-actions[bot]"
63
+ git config user.email "github-actions[bot]@users.noreply.github.com"
64
+ git add .github
65
+ git commit -m "chore: sync milestone #${MILESTONE_NUMBER} (${ACTION})"
66
+ echo "has_changes=true" >> "$GITHUB_OUTPUT"
67
+
68
+ - name: Push changes
69
+ if: steps.commit.outputs.has_changes == 'true'
70
+ run: git push
@@ -0,0 +1,59 @@
1
+ # Push all KickCat entities from local storage to GitHub
2
+ name: kickcat-push-all
3
+
4
+ on:
5
+ push:
6
+ branches: [main, master]
7
+ paths:
8
+ - '.github/**/*.yml'
9
+ - 'schemas/**'
10
+ - 'templates/**'
11
+ - 'package.json'
12
+ - 'package-lock.json'
13
+ workflow_dispatch:
14
+
15
+ permissions:
16
+ contents: write
17
+ issues: write
18
+
19
+ jobs:
20
+ push-all:
21
+ if: "${{ !(github.event_name == 'push' && (github.actor == 'github-actions[bot]' || startsWith(github.event.head_commit.message || '', 'chore: sync '))) }}"
22
+ runs-on: ubuntu-latest
23
+ steps:
24
+ - name: Checkout
25
+ uses: actions/checkout@v4
26
+ with:
27
+ fetch-depth: 0
28
+
29
+ - name: Setup Node.js
30
+ uses: actions/setup-node@v4
31
+ with:
32
+ node-version: 20
33
+
34
+ - name: Push entities to GitHub
35
+ env:
36
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
37
+ run: |
38
+ set -euo pipefail
39
+ npx @aliaksandarpratashchyk/kickcat entity push all --log-level=info
40
+
41
+ - name: Commit changes
42
+ id: commit
43
+ run: |
44
+ set -euo pipefail
45
+
46
+ if git diff --quiet -- .github; then
47
+ echo "has_changes=false" >> "$GITHUB_OUTPUT"
48
+ exit 0
49
+ fi
50
+
51
+ git config user.name "github-actions[bot]"
52
+ git config user.email "github-actions[bot]@users.noreply.github.com"
53
+ git add .github
54
+ git commit -m "chore: push all KickCat entities"
55
+ echo "has_changes=true" >> "$GITHUB_OUTPUT"
56
+
57
+ - name: Push changes
58
+ if: steps.commit.outputs.has_changes == 'true'
59
+ run: git push