Skip to content

Commit 0c7ae60

Browse files
Add desktop CI/CD workflows and Git hooks
1 parent 8eafc59 commit 0c7ae60

12 files changed

Lines changed: 1203 additions & 0 deletions

File tree

apps/desktop/.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@Gerome-Elassaad
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
name: 'Bug report'
2+
description: Create a report to help us improve
3+
body:
4+
- type: markdown
5+
attributes:
6+
value: |
7+
Thank you for reporting an issue :pray:.
8+
9+
This issue tracker is for bugs and issues found with [CodinIT.dev](https://codinit.dev).
10+
If you experience issues related to WebContainer, please file an issue in the official [StackBlitz WebContainer repo](https://github.com/stackblitz/webcontainer-core).
11+
12+
The more information you fill in, the better we can help you.
13+
- type: textarea
14+
id: description
15+
attributes:
16+
label: Describe the bug
17+
description: Provide a clear and concise description of what you're running into.
18+
validations:
19+
required: true
20+
- type: input
21+
id: link
22+
attributes:
23+
label: Link to the CodinIT URL that caused the error
24+
description: Please do not delete it after reporting!
25+
validations:
26+
required: true
27+
- type: textarea
28+
id: steps
29+
attributes:
30+
label: Steps to reproduce
31+
description: Describe the steps we have to take to reproduce the behavior.
32+
placeholder: |
33+
1. Go to '...'
34+
2. Click on '....'
35+
3. Scroll down to '....'
36+
4. See error
37+
validations:
38+
required: true
39+
- type: textarea
40+
id: expected
41+
attributes:
42+
label: Expected behavior
43+
description: Provide a clear and concise description of what you expected to happen.
44+
validations:
45+
required: true
46+
- type: textarea
47+
id: screenshots
48+
attributes:
49+
label: Screen Recording / Screenshot
50+
description: If applicable, **please include a screen recording** (preferably) or screenshot showcasing the issue. This will assist us in resolving your issue <u>quickly</u>.
51+
- type: textarea
52+
id: platform
53+
attributes:
54+
label: Platform
55+
value: |
56+
- OS: [e.g. macOS, Windows, Linux]
57+
- Browser: [e.g. Chrome, Safari, Firefox]
58+
- Version: [e.g. 91.1]
59+
- type: input
60+
id: provider
61+
attributes:
62+
label: Provider Used
63+
description: Tell us the provider you are using.
64+
- type: input
65+
id: model
66+
attributes:
67+
label: Model Used
68+
description: Tell us the model you are using.
69+
- type: textarea
70+
id: additional
71+
attributes:
72+
label: Additional context
73+
description: Add any other context about the problem here.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
blank_issues_enabled: false
2+
contact_links:
3+
- name: Community Discussion
4+
url: https://github.com/Gerome-Elassaad/codingit/discussions
5+
about: Ask questions and discuss with other CodinIT.dev users
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: Setup and Build
2+
description: Generic setup action
3+
inputs:
4+
pnpm-version:
5+
description: 'Version of pnpm to use'
6+
required: false
7+
default: '10.18.0'
8+
node-version:
9+
description: 'Version of Node.js to use'
10+
required: false
11+
default: '20.18.0'
12+
13+
runs:
14+
using: composite
15+
16+
steps:
17+
- uses: pnpm/action-setup@v4
18+
with:
19+
version: ${{ inputs.pnpm-version }}
20+
run_install: false
21+
22+
- name: Set Node.js version to ${{ inputs.node-version }}
23+
uses: actions/setup-node@v4
24+
with:
25+
node-version: ${{ inputs.node-version }}
26+
cache: pnpm
27+
28+
- name: Install dependencies and build project
29+
shell: bash
30+
run: |
31+
pnpm install
32+
pnpm run build
Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
#!/usr/bin/env bash
2+
3+
# Ensure we're running in bash
4+
if [ -z "$BASH_VERSION" ]; then
5+
echo "This script requires bash. Please run with: bash $0" >&2
6+
exit 1
7+
fi
8+
9+
# Ensure we're using bash 4.0 or later for associative arrays
10+
if ((BASH_VERSINFO[0] < 4)); then
11+
echo "This script requires bash version 4 or later" >&2
12+
echo "Current bash version: $BASH_VERSION" >&2
13+
exit 1
14+
fi
15+
16+
# Set default values for required environment variables if not in GitHub Actions
17+
if [ -z "$GITHUB_ACTIONS" ]; then
18+
: "${GITHUB_SERVER_URL:=https://github.com}"
19+
: "${GITHUB_REPOSITORY:=gerome-elassaad/codinit-app}"
20+
: "${GITHUB_OUTPUT:=/tmp/github_output}"
21+
touch "$GITHUB_OUTPUT"
22+
23+
# Running locally
24+
echo "Running locally - checking for upstream remote..."
25+
MAIN_REMOTE="origin"
26+
if git remote -v | grep -q "upstream"; then
27+
MAIN_REMOTE="upstream"
28+
fi
29+
MAIN_BRANCH="main" # or "master" depending on your repository
30+
31+
# Ensure we have latest tags
32+
git fetch ${MAIN_REMOTE} --tags
33+
34+
# Use the remote reference for git log
35+
GITLOG_REF="${MAIN_REMOTE}/${MAIN_BRANCH}"
36+
else
37+
# Running in GitHub Actions
38+
GITLOG_REF="HEAD"
39+
fi
40+
41+
# Get the latest tag
42+
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
43+
44+
# Start changelog file
45+
echo "# 🚀 Release v${NEW_VERSION}" > changelog.md
46+
echo "" >> changelog.md
47+
echo "## What's Changed 🌟" >> changelog.md
48+
echo "" >> changelog.md
49+
50+
if [ -z "$LATEST_TAG" ]; then
51+
echo "### 🎉 First Release" >> changelog.md
52+
echo "" >> changelog.md
53+
echo "Exciting times! This marks our first release. Thanks to everyone who contributed! 🙌" >> changelog.md
54+
echo "" >> changelog.md
55+
COMPARE_BASE="$(git rev-list --max-parents=0 HEAD)"
56+
else
57+
echo "### 🔄 Changes since $LATEST_TAG" >> changelog.md
58+
echo "" >> changelog.md
59+
COMPARE_BASE="$LATEST_TAG"
60+
fi
61+
62+
# Function to extract conventional commit type and associated emoji
63+
get_commit_type() {
64+
local msg="$1"
65+
if [[ $msg =~ ^feat(\(.+\))?:|^feature(\(.+\))?: ]]; then echo "✨ Features"
66+
elif [[ $msg =~ ^fix(\(.+\))?: ]]; then echo "🐛 Bug Fixes"
67+
elif [[ $msg =~ ^docs(\(.+\))?: ]]; then echo "📚 Documentation"
68+
elif [[ $msg =~ ^style(\(.+\))?: ]]; then echo "💎 Styles"
69+
elif [[ $msg =~ ^refactor(\(.+\))?: ]]; then echo "♻️ Code Refactoring"
70+
elif [[ $msg =~ ^perf(\(.+\))?: ]]; then echo "⚡ Performance Improvements"
71+
elif [[ $msg =~ ^test(\(.+\))?: ]]; then echo "🧪 Tests"
72+
elif [[ $msg =~ ^build(\(.+\))?: ]]; then echo "🛠️ Build System"
73+
elif [[ $msg =~ ^ci(\(.+\))?: ]]; then echo "⚙️ CI"
74+
elif [[ $msg =~ ^chore(\(.+\))?: ]]; then echo "" # Skip chore commits
75+
else echo "🔍 Other Changes" # Default category with emoji
76+
fi
77+
}
78+
79+
# Initialize associative arrays
80+
declare -A CATEGORIES
81+
declare -A COMMITS_BY_CATEGORY
82+
declare -A ALL_AUTHORS
83+
declare -A NEW_CONTRIBUTORS
84+
85+
# Get all historical authors before the compare base
86+
while IFS= read -r author; do
87+
ALL_AUTHORS["$author"]=1
88+
done < <(git log "${COMPARE_BASE}" --pretty=format:"%ae" | sort -u)
89+
90+
# Process all commits since last tag
91+
while IFS= read -r commit_line; do
92+
if [[ ! $commit_line =~ ^[a-f0-9]+\| ]]; then
93+
echo "WARNING: Skipping invalid commit line format: $commit_line" >&2
94+
continue
95+
fi
96+
97+
HASH=$(echo "$commit_line" | cut -d'|' -f1)
98+
COMMIT_MSG=$(echo "$commit_line" | cut -d'|' -f2)
99+
BODY=$(echo "$commit_line" | cut -d'|' -f3)
100+
# Skip if hash doesn't match the expected format
101+
if [[ ! $HASH =~ ^[a-f0-9]{40}$ ]]; then
102+
continue
103+
fi
104+
105+
HASH=$(echo "$commit_line" | cut -d'|' -f1)
106+
COMMIT_MSG=$(echo "$commit_line" | cut -d'|' -f2)
107+
BODY=$(echo "$commit_line" | cut -d'|' -f3)
108+
109+
110+
# Validate hash format
111+
if [[ ! $HASH =~ ^[a-f0-9]{40}$ ]]; then
112+
echo "WARNING: Invalid commit hash format: $HASH" >&2
113+
continue
114+
fi
115+
116+
# Check if it's a merge commit
117+
if [[ $COMMIT_MSG =~ Merge\ pull\ request\ #([0-9]+) ]]; then
118+
# echo "Processing as merge commit" >&2
119+
PR_NUM="${BASH_REMATCH[1]}"
120+
121+
# Extract the PR title from the merge commit body
122+
PR_TITLE=$(echo "$BODY" | grep -v "^Merge pull request" | head -n 1)
123+
124+
# Only process if it follows conventional commit format
125+
CATEGORY=$(get_commit_type "$PR_TITLE")
126+
127+
if [ -n "$CATEGORY" ]; then # Only process if it's a conventional commit
128+
# Get PR author's GitHub username
129+
GITHUB_USERNAME=$(gh pr view "$PR_NUM" --json author --jq '.author.login')
130+
131+
if [ -n "$GITHUB_USERNAME" ]; then
132+
# Check if this is a first-time contributor
133+
AUTHOR_EMAIL=$(git show -s --format='%ae' "$HASH")
134+
if [ -z "${ALL_AUTHORS[$AUTHOR_EMAIL]}" ]; then
135+
NEW_CONTRIBUTORS["$GITHUB_USERNAME"]=1
136+
ALL_AUTHORS["$AUTHOR_EMAIL"]=1
137+
fi
138+
139+
CATEGORIES["$CATEGORY"]=1
140+
COMMITS_BY_CATEGORY["$CATEGORY"]+="* ${PR_TITLE#*: } ([#$PR_NUM](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/pull/$PR_NUM)) by @$GITHUB_USERNAME"$'\n'
141+
else
142+
COMMITS_BY_CATEGORY["$CATEGORY"]+="* ${PR_TITLE#*: } ([#$PR_NUM](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/pull/$PR_NUM))"$'\n'
143+
fi
144+
fi
145+
# Check if it's a squash merge by looking for (#NUMBER) pattern
146+
elif [[ $COMMIT_MSG =~ \(#([0-9]+)\) ]]; then
147+
# echo "Processing as squash commit" >&2
148+
PR_NUM="${BASH_REMATCH[1]}"
149+
150+
# Only process if it follows conventional commit format
151+
CATEGORY=$(get_commit_type "$COMMIT_MSG")
152+
153+
if [ -n "$CATEGORY" ]; then # Only process if it's a conventional commit
154+
# Get PR author's GitHub username
155+
GITHUB_USERNAME=$(gh pr view "$PR_NUM" --json author --jq '.author.login')
156+
157+
if [ -n "$GITHUB_USERNAME" ]; then
158+
# Check if this is a first-time contributor
159+
AUTHOR_EMAIL=$(git show -s --format='%ae' "$HASH")
160+
if [ -z "${ALL_AUTHORS[$AUTHOR_EMAIL]}" ]; then
161+
NEW_CONTRIBUTORS["$GITHUB_USERNAME"]=1
162+
ALL_AUTHORS["$AUTHOR_EMAIL"]=1
163+
fi
164+
165+
CATEGORIES["$CATEGORY"]=1
166+
COMMIT_TITLE=${COMMIT_MSG%% (#*} # Remove the PR number suffix
167+
COMMIT_TITLE=${COMMIT_TITLE#*: } # Remove the type prefix
168+
COMMITS_BY_CATEGORY["$CATEGORY"]+="* $COMMIT_TITLE ([#$PR_NUM](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/pull/$PR_NUM)) by @$GITHUB_USERNAME"$'\n'
169+
else
170+
COMMIT_TITLE=${COMMIT_MSG%% (#*} # Remove the PR number suffix
171+
COMMIT_TITLE=${COMMIT_TITLE#*: } # Remove the type prefix
172+
COMMITS_BY_CATEGORY["$CATEGORY"]+="* $COMMIT_TITLE ([#$PR_NUM](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/pull/$PR_NUM))"$'\n'
173+
fi
174+
fi
175+
176+
else
177+
# echo "Processing as regular commit" >&2
178+
# Process conventional commits without PR numbers
179+
CATEGORY=$(get_commit_type "$COMMIT_MSG")
180+
181+
if [ -n "$CATEGORY" ]; then # Only process if it's a conventional commit
182+
# Get commit author info
183+
AUTHOR_EMAIL=$(git show -s --format='%ae' "$HASH")
184+
185+
# Try to get GitHub username using gh api
186+
if [ -n "$GITHUB_ACTIONS" ] || command -v gh >/dev/null 2>&1; then
187+
GITHUB_USERNAME=$(gh api "/repos/${GITHUB_REPOSITORY}/commits/${HASH}" --jq '.author.login' 2>/dev/null)
188+
fi
189+
190+
if [ -n "$GITHUB_USERNAME" ]; then
191+
# If we got GitHub username, use it
192+
if [ -z "${ALL_AUTHORS[$AUTHOR_EMAIL]}" ]; then
193+
NEW_CONTRIBUTORS["$GITHUB_USERNAME"]=1
194+
ALL_AUTHORS["$AUTHOR_EMAIL"]=1
195+
fi
196+
197+
CATEGORIES["$CATEGORY"]=1
198+
COMMIT_TITLE=${COMMIT_MSG#*: } # Remove the type prefix
199+
COMMITS_BY_CATEGORY["$CATEGORY"]+="* $COMMIT_TITLE (${HASH:0:7}) by @$GITHUB_USERNAME"$'\n'
200+
else
201+
# Fallback to git author name if no GitHub username found
202+
AUTHOR_NAME=$(git show -s --format='%an' "$HASH")
203+
204+
if [ -z "${ALL_AUTHORS[$AUTHOR_EMAIL]}" ]; then
205+
NEW_CONTRIBUTORS["$AUTHOR_NAME"]=1
206+
ALL_AUTHORS["$AUTHOR_EMAIL"]=1
207+
fi
208+
209+
CATEGORIES["$CATEGORY"]=1
210+
COMMIT_TITLE=${COMMIT_MSG#*: } # Remove the type prefix
211+
COMMITS_BY_CATEGORY["$CATEGORY"]+="* $COMMIT_TITLE (${HASH:0:7}) by $AUTHOR_NAME"$'\n'
212+
fi
213+
fi
214+
fi
215+
216+
done < <(git log "${COMPARE_BASE}..${GITLOG_REF}" --pretty=format:"%H|%s|%b" --reverse --first-parent)
217+
218+
# Write categorized commits to changelog with their emojis
219+
for category in "✨ Features" "🐛 Bug Fixes" "📚 Documentation" "💎 Styles" "♻️ Code Refactoring" "⚡ Performance Improvements" "🧪 Tests" "🛠️ Build System" "⚙️ CI" "🔍 Other Changes"; do
220+
if [ -n "${COMMITS_BY_CATEGORY[$category]}" ]; then
221+
echo "### $category" >> changelog.md
222+
echo "" >> changelog.md
223+
echo "${COMMITS_BY_CATEGORY[$category]}" >> changelog.md
224+
echo "" >> changelog.md
225+
fi
226+
done
227+
228+
# Add first-time contributors section if there are any
229+
if [ ${#NEW_CONTRIBUTORS[@]} -gt 0 ]; then
230+
echo "## ✨ First-time Contributors" >> changelog.md
231+
echo "" >> changelog.md
232+
echo "A huge thank you to our amazing new contributors! Your first contribution marks the start of an exciting journey! 🌟" >> changelog.md
233+
echo "" >> changelog.md
234+
# Use readarray to sort the keys
235+
readarray -t sorted_contributors < <(printf '%s\n' "${!NEW_CONTRIBUTORS[@]}" | sort)
236+
for github_username in "${sorted_contributors[@]}"; do
237+
echo "* 🌟 [@$github_username](https://github.com/$github_username)" >> changelog.md
238+
done
239+
echo "" >> changelog.md
240+
fi
241+
242+
# Add compare link if not first release
243+
if [ -n "$LATEST_TAG" ]; then
244+
echo "## 📈 Stats" >> changelog.md
245+
echo "" >> changelog.md
246+
echo "**Full Changelog**: [\`$LATEST_TAG..v${NEW_VERSION}\`](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/compare/$LATEST_TAG...v${NEW_VERSION})" >> changelog.md
247+
fi
248+
249+
# Output the changelog content
250+
CHANGELOG_CONTENT=$(cat changelog.md)
251+
{
252+
echo "content<<EOF"
253+
echo "$CHANGELOG_CONTENT"
254+
echo "EOF"
255+
} >> "$GITHUB_OUTPUT"
256+
257+
# Also print to stdout for local testing
258+
echo "Generated changelog:"
259+
echo "==================="
260+
cat changelog.md
261+
echo "==================="

0 commit comments

Comments
 (0)