github-delivery-os 1.0.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.
@@ -0,0 +1,84 @@
1
+ name: 🐞 Bug Report
2
+ description: Report a defect or unexpected behavior
3
+ title: "[BUG] "
4
+ labels:
5
+ - bug
6
+ - qa
7
+
8
+ body:
9
+ - type: checkboxes
10
+ id: platform
11
+ attributes:
12
+ label: Platform(s) Affected
13
+ description: Select all platforms where this issue occurs
14
+ options:
15
+ - label: Android
16
+ - label: iOS
17
+ - label: Web
18
+ - label: Backend / API
19
+ validations:
20
+ required: true
21
+
22
+ - type: dropdown
23
+ id: severity
24
+ attributes:
25
+ label: Severity
26
+ options:
27
+ - P0 – Blocker (Crash / Data Loss)
28
+ - P1 – Critical (Core flow broken)
29
+ - P2 – Major (Workaround exists)
30
+ - P3 – Minor (UI / Cosmetic)
31
+ validations:
32
+ required: true
33
+
34
+ - type: input
35
+ id: build
36
+ attributes:
37
+ label: "Build / Version"
38
+ placeholder: "e.g. 4227, v1.3.0"
39
+ validations:
40
+ required: true
41
+
42
+ - type: textarea
43
+ id: summary
44
+ attributes:
45
+ label: Bug Summary
46
+ description: One clear sentence describing the issue
47
+ validations:
48
+ required: true
49
+
50
+ - type: textarea
51
+ id: steps
52
+ attributes:
53
+ label: Steps to Reproduce
54
+ description: Provide clear, numbered steps
55
+ validations:
56
+ required: true
57
+
58
+ - type: textarea
59
+ id: expected
60
+ attributes:
61
+ label: Expected Result
62
+ validations:
63
+ required: true
64
+
65
+ - type: textarea
66
+ id: actual
67
+ attributes:
68
+ label: Actual Result
69
+ validations:
70
+ required: true
71
+
72
+ - type: textarea
73
+ id: environment
74
+ attributes:
75
+ label: Test Environment
76
+ description: Device, OS, browser, network, etc.
77
+ validations:
78
+ required: true
79
+
80
+ - type: textarea
81
+ id: evidence
82
+ attributes:
83
+ label: Logs / Screenshots / Videos
84
+ description: Attach any supporting evidence
@@ -0,0 +1,2 @@
1
+ blank_issues_enabled: true
2
+ contact_links: []
@@ -0,0 +1,51 @@
1
+ name: "PRODUCTION RELEASE & QA SIGN-OFF FORM"
2
+ description: "Formal Production Release Governance & QA Sign-Off"
3
+ title: "PRODUCTION RELEASE - [Project Name] - vX.X.X"
4
+ labels: ["release", "production", "approval"]
5
+
6
+ body:
7
+ - type: input
8
+ id: sprint_reference
9
+ attributes:
10
+ label: "Sprint Reference (Sprint Planning Issue #)"
11
+ placeholder: "#45"
12
+ validations:
13
+ required: true
14
+
15
+ - type: input
16
+ id: version
17
+ attributes:
18
+ label: "Version / Build Number"
19
+ placeholder: "v2.4.1"
20
+ validations:
21
+ required: true
22
+
23
+ - type: textarea
24
+ id: release_summary
25
+ attributes:
26
+ label: "Release Summary"
27
+ validations:
28
+ required: true
29
+
30
+ - type: textarea
31
+ id: qa_summary
32
+ attributes:
33
+ label: "QA Summary + Evidence Links"
34
+ placeholder: "Link QA Request issues, screenshots folder, logs, etc."
35
+
36
+ - type: dropdown
37
+ id: qa_recommendation
38
+ attributes:
39
+ label: "Overall QA Recommendation"
40
+ options:
41
+ - "Approve for Production"
42
+ - "Reject Release"
43
+ - "Conditional Approval"
44
+
45
+ - type: dropdown
46
+ id: deployment_authorized
47
+ attributes:
48
+ label: "Deployment Authorized"
49
+ options:
50
+ - "Yes"
51
+ - "No"
@@ -0,0 +1,55 @@
1
+ name: "QA REQUEST"
2
+ description: "Request QA testing for a sprint task or bug fix"
3
+ title: "QA REQUEST - [Feature/Issue]"
4
+ labels: ["qa-request"]
5
+
6
+ body:
7
+ - type: input
8
+ id: related_issue
9
+ attributes:
10
+ label: "Related Sprint Task Issue (#)"
11
+ placeholder: "#101"
12
+ validations:
13
+ required: true
14
+
15
+ - type: textarea
16
+ id: what_to_test
17
+ attributes:
18
+ label: "What to Test"
19
+ validations:
20
+ required: true
21
+
22
+ - type: textarea
23
+ id: env_build
24
+ attributes:
25
+ label: "Environment + Build Link"
26
+ placeholder: |
27
+ Staging build link:
28
+ TestFlight / APK / Web URL:
29
+
30
+ - type: textarea
31
+ id: acceptance_criteria
32
+ attributes:
33
+ label: "Acceptance Criteria"
34
+ placeholder: |
35
+ - Expected behavior
36
+ - Edge cases
37
+
38
+ - type: checkboxes
39
+ id: artifacts
40
+ attributes:
41
+ label: "Artifacts"
42
+ options:
43
+ - label: "Screenshots"
44
+ - label: "Logs"
45
+ - label: "Video Recording"
46
+ - label: "Crash Report"
47
+
48
+ - type: dropdown
49
+ id: qa_outcome
50
+ attributes:
51
+ label: "QA Outcome"
52
+ options:
53
+ - "Pending"
54
+ - "Pass"
55
+ - "Fail"
@@ -0,0 +1,68 @@
1
+ name: "SPRINT PLANNING"
2
+ description: "Plan sprint scope; each feature becomes a task issue"
3
+ title: "SPRINT - [Sprint Name]"
4
+ labels: ["sprint", "planning"]
5
+
6
+ body:
7
+ - type: markdown
8
+ attributes:
9
+ value: |
10
+ # SPRINT PLANNING
11
+
12
+ Enter ONE feature per line.
13
+ Do not use bullets.
14
+ Do not number items.
15
+ Do not combine multiple features on one line.
16
+
17
+ - type: input
18
+ id: sprint_name
19
+ attributes:
20
+ label: "Sprint Name"
21
+ placeholder: "Sprint 12 - March 1–14"
22
+ validations:
23
+ required: true
24
+
25
+ - type: input
26
+ id: sprint_start
27
+ attributes:
28
+ label: "Sprint Start"
29
+ description: "Format: YYYY-MM-DD"
30
+ placeholder: "2026-03-07"
31
+ validations:
32
+ required: true
33
+
34
+ - type: input
35
+ id: sprint_end
36
+ attributes:
37
+ label: "Sprint End"
38
+ description: "Format: YYYY-MM-DD"
39
+ placeholder: "2026-03-21"
40
+ validations:
41
+ required: true
42
+
43
+ - type: textarea
44
+ id: sprint_goal
45
+ attributes:
46
+ label: "Sprint Goal"
47
+ validations:
48
+ required: true
49
+
50
+ - type: textarea
51
+ id: sprint_features
52
+ attributes:
53
+ label: "Sprint Features (One Per Line)"
54
+ placeholder: |
55
+ Implement burn-down chart
56
+ Add sprint health indicator
57
+ Prevent duplicate child creation
58
+ validations:
59
+ required: true
60
+
61
+ - type: dropdown
62
+ id: sprint_approval
63
+ attributes:
64
+ label: "Sprint Approved"
65
+ options:
66
+ - "Pending"
67
+ - "Approved"
68
+ - "Rejected"
@@ -0,0 +1,91 @@
1
+ name: "Task"
2
+ description: "Create a structured task with owner, priority, and acceptance criteria"
3
+ title: "TASK - "
4
+ labels: ["task"]
5
+
6
+ body:
7
+ - type: markdown
8
+ attributes:
9
+ value: |
10
+ ## 🧩 Task Overview
11
+ Fill out the details below to create a structured, trackable task.
12
+
13
+ - type: input
14
+ id: title_summary
15
+ attributes:
16
+ label: "Task Summary"
17
+ description: "One-line description of the task"
18
+ placeholder: "Implement login validation error handling"
19
+ validations:
20
+ required: true
21
+
22
+ - type: textarea
23
+ id: description
24
+ attributes:
25
+ label: "Description"
26
+ description: "Provide context and details"
27
+ placeholder: "Explain what needs to be done and why..."
28
+ validations:
29
+ required: true
30
+
31
+ - type: dropdown
32
+ id: owner
33
+ attributes:
34
+ label: "Owner (Select if applicable)"
35
+ description: "Select the responsible person"
36
+ options:
37
+ - Unassigned
38
+ - Other (Specify Below)
39
+ validations:
40
+ required: true
41
+
42
+ - type: input
43
+ id: custom_owner
44
+ attributes:
45
+ label: "Custom Owner (if 'Other')"
46
+ description: "Type name if not listed above"
47
+ placeholder: "Enter full name"
48
+
49
+ - type: dropdown
50
+ id: priority
51
+ attributes:
52
+ label: "Priority"
53
+ options:
54
+ - P0 - Critical
55
+ - P1 - High
56
+ - P2 - Medium
57
+ - P3 - Low
58
+ validations:
59
+ required: true
60
+
61
+ - type: dropdown
62
+ id: status
63
+ attributes:
64
+ label: "Status"
65
+ options:
66
+ - Backlog
67
+ - In Progress
68
+ - Blocked
69
+ - Ready for Review
70
+ - Done
71
+ validations:
72
+ required: true
73
+
74
+ - type: textarea
75
+ id: acceptance_criteria
76
+ attributes:
77
+ label: "Acceptance Criteria"
78
+ description: "Define what 'done' looks like"
79
+ placeholder: |
80
+ - [ ] Requirement 1
81
+ - [ ] Requirement 2
82
+ - [ ] Requirement 3
83
+ validations:
84
+ required: true
85
+
86
+ - type: textarea
87
+ id: artifacts
88
+ attributes:
89
+ label: "Artifacts / Links (Optional)"
90
+ description: "Add PR links, designs, screenshots, docs"
91
+ placeholder: "https://figma.com/..., https://github.com/..., etc."
@@ -0,0 +1,106 @@
1
+ name: Authorize Deployment on Dual Approval
2
+
3
+ on:
4
+ issue_comment:
5
+ types: [created]
6
+
7
+ permissions:
8
+ issues: write
9
+
10
+ jobs:
11
+ authorize:
12
+ if: github.event.issue && contains(github.event.issue.labels.*.name || fromJSON('[]'), 'production')
13
+ runs-on: ubuntu-latest
14
+ permissions:
15
+ issues: write
16
+
17
+ steps:
18
+ - name: Check Dual Approval (Flexible + Decline)
19
+ uses: actions/github-script@v7
20
+ env:
21
+ RELEASE_APPROVER: ${{ vars.RELEASE_APPROVER || 'release-approver' }}
22
+ QA_APPROVER: ${{ vars.QA_APPROVER || 'qa-approver' }}
23
+ with:
24
+ script: |
25
+ const issueNumber = context.issue.number;
26
+ const owner = context.repo.owner;
27
+ const repo = context.repo.repo;
28
+ const releaseApprover = process.env.RELEASE_APPROVER;
29
+ const qaApprover = process.env.QA_APPROVER;
30
+
31
+ const comments = await github.rest.issues.listComments({
32
+ owner,
33
+ repo,
34
+ issue_number: issueNumber
35
+ });
36
+
37
+ let releaseApproved = false;
38
+ let qaApproved = false;
39
+
40
+ for (const comment of comments.data) {
41
+ const body = (comment.body || "").trim().toLowerCase();
42
+
43
+ if (
44
+ comment.user.login === releaseApprover &&
45
+ /(declined|reject|not approved)/i.test(body)
46
+ ) {
47
+
48
+ await github.rest.issues.addLabels({
49
+ owner,
50
+ repo,
51
+ issue_number: issueNumber,
52
+ labels: ["declined"]
53
+ });
54
+
55
+ try {
56
+ await github.rest.issues.removeLabel({
57
+ owner,
58
+ repo,
59
+ issue_number: issueNumber,
60
+ name: "ready-for-deploy"
61
+ });
62
+ } catch (e) {}
63
+
64
+ await github.rest.issues.createComment({
65
+ owner,
66
+ repo,
67
+ issue_number: issueNumber,
68
+ body: "🔴 **Release Declined**\n\nThis release requires additional fixes before production deployment."
69
+ });
70
+
71
+ return;
72
+ }
73
+
74
+ if (
75
+ comment.user.login === releaseApprover &&
76
+ /^(approved|approve|ok|go ahead)/i.test(body)
77
+ ) {
78
+ releaseApproved = true;
79
+ }
80
+
81
+ if (
82
+ comment.user.login === qaApprover &&
83
+ /(qa approved|approved|qa ok|looks good)/i.test(body)
84
+ ) {
85
+ qaApproved = true;
86
+ }
87
+ }
88
+
89
+ if (releaseApproved && qaApproved) {
90
+
91
+ try {
92
+ await github.rest.issues.addLabels({
93
+ owner,
94
+ repo,
95
+ issue_number: issueNumber,
96
+ labels: ["ready-for-deploy"]
97
+ });
98
+ } catch (e) {}
99
+
100
+ await github.rest.issues.createComment({
101
+ owner,
102
+ repo,
103
+ issue_number: issueNumber,
104
+ body: "🟢🚀 **Deployment Authorized**\n\nDual approval received. This release is cleared for production deployment."
105
+ });
106
+ }
@@ -0,0 +1,25 @@
1
+ name: Auto-assign QA submissions
2
+
3
+ on:
4
+ issues:
5
+ types: [opened, labeled]
6
+
7
+ permissions:
8
+ issues: write
9
+
10
+ jobs:
11
+ assign:
12
+ if: |
13
+ (contains(github.event.issue.labels.*.name || fromJSON('[]'), 'qa') ||
14
+ contains(github.event.issue.labels.*.name || fromJSON('[]'), 'qa-request')) &&
15
+ vars.QA_ASSIGNEES != ''
16
+ runs-on: ubuntu-latest
17
+ permissions:
18
+ issues: write
19
+ steps:
20
+ # pozil/auto-assign-issue does not support 'labels' input; labels come from issue template (qa_request.yml)
21
+ - name: Assign QA team to QA submission issues
22
+ uses: pozil/auto-assign-issue@v1
23
+ with:
24
+ assignees: ${{ vars.QA_ASSIGNEES }}
25
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,135 @@
1
+ name: Update Sprint Progress + Intelligence + Auto Close
2
+
3
+ on:
4
+ issues:
5
+ types: [closed]
6
+
7
+ permissions:
8
+ issues: write
9
+
10
+ jobs:
11
+ update-sprint:
12
+ runs-on: ubuntu-latest
13
+ permissions:
14
+ issues: write
15
+
16
+ steps:
17
+ - name: Update sprint health, burn-down, and auto-close
18
+ uses: actions/github-script@v7
19
+ env:
20
+ TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
21
+ TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
22
+ with:
23
+ script: |
24
+ const issue = context.payload.issue;
25
+ const body = issue.body || "";
26
+
27
+ const parentMatch = body.match(/Parent Sprint:\s*#(\d+)/);
28
+ if (!parentMatch) return;
29
+
30
+ const sprintNumber = parseInt(parentMatch[1]);
31
+
32
+ const sprintIssue = await github.rest.issues.get({
33
+ owner: context.repo.owner,
34
+ repo: context.repo.repo,
35
+ issue_number: sprintNumber
36
+ });
37
+
38
+ const sprintBody = sprintIssue.data.body || "";
39
+
40
+ let startDate, endDate;
41
+ const dateMatch1 = sprintBody.match(/Sprint Dates[\s\S]*?(\d{4}-\d{2}-\d{2})\s*to\s*(\d{4}-\d{2}-\d{2})/i);
42
+ const dateMatch2a = sprintBody.match(/Sprint Start[\s\S]*?(\d{4}-\d{2}-\d{2})/i);
43
+ const dateMatch2b = sprintBody.match(/Sprint End[\s\S]*?(\d{4}-\d{2}-\d{2})/i);
44
+ if (dateMatch1) {
45
+ startDate = new Date(dateMatch1[1]);
46
+ endDate = new Date(dateMatch1[2]);
47
+ } else if (dateMatch2a && dateMatch2b) {
48
+ startDate = new Date(dateMatch2a[1]);
49
+ endDate = new Date(dateMatch2b[1]);
50
+ }
51
+ if (!startDate || !endDate) {
52
+ console.log("Sprint dates not found.");
53
+ return;
54
+ }
55
+ const now = new Date();
56
+
57
+ const totalDuration = endDate - startDate;
58
+ const elapsed = now - startDate;
59
+ const timePercent = Math.max(0, Math.min(100, Math.round((elapsed / totalDuration) * 100)));
60
+
61
+ const { data: allIssues } = await github.rest.issues.listForRepo({
62
+ owner: context.repo.owner,
63
+ repo: context.repo.repo,
64
+ state: "all",
65
+ per_page: 100
66
+ });
67
+
68
+ const children = allIssues.filter(i =>
69
+ i.body && i.body.includes(`Parent Sprint: #${sprintNumber}`)
70
+ );
71
+
72
+ const closedChildren = children.filter(i => i.state === "closed");
73
+
74
+ const progressPercent = children.length === 0
75
+ ? 0
76
+ : Math.round((closedChildren.length / children.length) * 100);
77
+
78
+ let healthEmoji = "🟢";
79
+ if (progressPercent < timePercent - 10) healthEmoji = "🔴";
80
+ else if (progressPercent < timePercent) healthEmoji = "🟡";
81
+
82
+ const totalBars = 20;
83
+ const filledBars = Math.round((progressPercent / 100) * totalBars);
84
+ const burnDown =
85
+ "█".repeat(filledBars) + "░".repeat(totalBars - filledBars);
86
+
87
+ let updatedBody = sprintBody;
88
+ updatedBody = updatedBody.replace(/## 🚦 Sprint Status[\s\S]*?---/g, "");
89
+
90
+ updatedBody +=
91
+ `\n\n---\n\n## 🚦 Sprint Status\n\n` +
92
+ `Progress: **${progressPercent}%**\n` +
93
+ `Time Elapsed: **${timePercent}%**\n\n` +
94
+ `Health: ${healthEmoji}\n\n` +
95
+ `### 📉 Burn-down\n` +
96
+ `\`${burnDown}\` ${progressPercent}%\n\n---`;
97
+
98
+ await github.rest.issues.update({
99
+ owner: context.repo.owner,
100
+ repo: context.repo.repo,
101
+ issue_number: sprintNumber,
102
+ body: updatedBody
103
+ });
104
+
105
+ if (progressPercent === 100) {
106
+
107
+ await github.rest.issues.update({
108
+ owner: context.repo.owner,
109
+ repo: context.repo.repo,
110
+ issue_number: sprintNumber,
111
+ state: "closed"
112
+ });
113
+
114
+ await github.rest.issues.createComment({
115
+ owner: context.repo.owner,
116
+ repo: context.repo.repo,
117
+ issue_number: sprintNumber,
118
+ body: "🎉 All sprint tasks complete. Sprint automatically closed."
119
+ });
120
+
121
+ if (process.env.TELEGRAM_BOT_TOKEN && process.env.TELEGRAM_CHAT_ID) {
122
+ await fetch(`https://api.telegram.org/bot${process.env.TELEGRAM_BOT_TOKEN}/sendMessage`, {
123
+ method: "POST",
124
+ headers: { "Content-Type": "application/json" },
125
+ body: JSON.stringify({
126
+ chat_id: process.env.TELEGRAM_CHAT_ID,
127
+ text:
128
+ `🚀 Sprint Completed!\n\n` +
129
+ `${sprintIssue.data.title}\n\n` +
130
+ `Progress: 100%\n` +
131
+ `Repository: ${context.repo.repo}`
132
+ })
133
+ });
134
+ }
135
+ }
@@ -0,0 +1,54 @@
1
+ name: Notify Release Approver
2
+
3
+ on:
4
+ issues:
5
+ types: [opened]
6
+
7
+ permissions:
8
+ issues: write
9
+
10
+ jobs:
11
+ notify:
12
+ if: contains(github.event.issue.labels.*.name || fromJSON('[]'), 'production')
13
+ runs-on: ubuntu-latest
14
+ permissions:
15
+ issues: write
16
+
17
+ steps:
18
+ - name: Post Approval Comment
19
+ uses: actions/github-script@v7
20
+ env:
21
+ RELEASE_APPROVER: ${{ vars.RELEASE_APPROVER || 'release-approver' }}
22
+ PROJECT_NAME: ${{ vars.PROJECT_NAME || '' }}
23
+ with:
24
+ script: |
25
+ const issueTitle = context.payload.issue.title;
26
+ const issueBody = context.payload.issue.body || "";
27
+ const approver = process.env.RELEASE_APPROVER;
28
+ const projectName = process.env.PROJECT_NAME;
29
+
30
+ let sprintRef = "Not specified";
31
+ const sprintMatch = issueBody.match(/#\d+/);
32
+ if (sprintMatch) sprintRef = sprintMatch[0];
33
+
34
+ let qaRecommendation = "Not specified";
35
+ if (issueBody.includes("Approve for Production")) qaRecommendation = "Approve for Production";
36
+ else if (issueBody.includes("Reject Release")) qaRecommendation = "Reject Release";
37
+ else if (issueBody.includes("Conditional Approval")) qaRecommendation = "Conditional Approval";
38
+
39
+ const projectLine = projectName ? "**Project:** " + projectName + "\n\n" : "";
40
+ const commentBody =
41
+ "🚨 @" + approver + " Production Release requires approval.\n\n" +
42
+ projectLine +
43
+ "**Issue:** " + issueTitle + "\n\n" +
44
+ "**Linked Sprint:** " + sprintRef + "\n\n" +
45
+ "**QA Recommendation:** " + qaRecommendation + "\n\n" +
46
+ "Please review the sprint delivery and QA sign-off details above before approving deployment.\n\n" +
47
+ "🔒 Deployment must not proceed without your approval.";
48
+
49
+ await github.rest.issues.createComment({
50
+ owner: context.repo.owner,
51
+ repo: context.repo.repo,
52
+ issue_number: context.issue.number,
53
+ body: commentBody
54
+ });