Skip to content

Commit b063ecb

Browse files
authored
Merge pull request #601 from AOSSIE-Org/dev
Release v3.0.0
2 parents 1cc1dca + 9b90b2e commit b063ecb

File tree

77 files changed

+12165
-1229
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+12165
-1229
lines changed

.github/workflows/build_and_deploy.yml

Lines changed: 56 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,79 +4,90 @@ on:
44
push:
55
branches:
66
- master
7-
pull_request:
8-
types: [closed]
9-
branches:
10-
- master
7+
- deploy-actions
118
workflow_dispatch:
129

1310
jobs:
14-
build:
11+
build_android:
12+
name: Build Android APK
1513
runs-on: ubuntu-latest
16-
14+
env:
15+
JAVA_VERSION: 21.0.6
16+
FLUTTER_VERSION: 3.35.2
17+
APK_PATH: build/app/outputs/flutter-apk/app-release.apk
18+
KEYSTORE_PATH: android/upload-keystore.jks
19+
KEY_PROPS_PATH: android/key.properties
20+
FIREBASE_OPTIONS_PATH: lib/firebase_options.dart
21+
GOOGLE_SERVICES_ANDROID_PATH: android/app/google-services.json
22+
APPWRITE_PROJECT_ID: ${{ secrets.APPWRITE_PROJECT_ID }}
1723
steps:
18-
# 1. Remove Cached Flutter Installation
19-
- name: Remove Cached Flutter Installation
20-
run: rm -rf $HOME/.flutter
24+
- name: Checkout repository
25+
uses: actions/checkout@v4
2126

22-
- name: Clean up old build files
23-
run: |
24-
rm -rf build/app/outputs/bundle/release/*
27+
- name: Setup Java
28+
uses: actions/setup-java@v4
29+
with:
30+
distribution: zulu
31+
java-version: ${{ env.JAVA_VERSION }}
2532

26-
# 2. Checkout repository
27-
- name: Checkout code
28-
uses: actions/checkout@v4
33+
- name: Setup Android SDK
34+
uses: android-actions/setup-android@v3
2935

30-
# 3. Install Flutter SDK
31-
- name: Install Flutter
36+
- name: Setup Flutter
3237
uses: subosito/flutter-action@v2
3338
with:
34-
flutter-version: 3.35.2
39+
flutter-version: ${{ env.FLUTTER_VERSION }}
3540

36-
# 4. Verify Flutter and Dart Versions
37-
- name: Verify Flutter Installation
38-
run: |
39-
flutter --version
40-
dart --version
41+
- name: Decode Android keystore
42+
run: echo "${{ secrets.ANDROID_KEYSTORE }}" | base64 --decode > ${{ env.KEYSTORE_PATH }}
4143

42-
# 6. Install Flutter dependencies
43-
- name: Install Flutter Dependencies
44+
- name: Decode Android key properties
45+
run: echo "${{ secrets.ANDROID_KEY_PROPERTIES }}" | base64 --decode > ${{ env.KEY_PROPS_PATH }}
46+
47+
- name: Decode Android Google Services JSON
48+
run: echo "${{ secrets.GOOGLE_SERVICES_ANDROID }}" | base64 --decode > ${{ env.GOOGLE_SERVICES_ANDROID_PATH }}
49+
50+
- name: Decode Firebase Options
51+
run: echo "${{ secrets.FIREBASE_OPTIONS }}" | base64 --decode > ${{ env.FIREBASE_OPTIONS_PATH }}
52+
53+
- name: Install Flutter dependencies
4454
run: flutter pub get
4555

46-
# 7. Build Android APK
47-
- name: Build Android App Bundle
48-
run: flutter build apk --release --split-per-abi
56+
- name: Run tests
57+
run: flutter test
58+
59+
- name: Build Android APK
60+
run: |
61+
flutter build apk --release \
62+
--dart-define=APPWRITE_BASE_DOMAIN=${{ secrets.APPWRITE_BASE_DOMAIN }} \
63+
--dart-define=APPWRITE_PROJECT_ID=${{ secrets.APPWRITE_PROJECT_ID }}
64+
65+
- name: Verify APK file existence
66+
run: ls -lh ${{ env.APK_PATH }}
4967

50-
# 8. Upload build artifacts
51-
- name: Upload APK as an artifact
68+
- name: Upload APK artifact
5269
uses: actions/upload-artifact@v4
5370
with:
54-
name: app-release-apks
55-
path: build/app/outputs/apk/release/*.apk
71+
name: apk-release
72+
path: ${{ env.APK_PATH }}
5673

57-
release:
74+
deploy_github_release:
75+
name: Deploy to GitHub Release
5876
runs-on: ubuntu-latest
59-
needs: build
77+
needs: build_android
6078
permissions:
6179
contents: write
6280
steps:
63-
# 1. Checkout repository
64-
- name: Checkout code
65-
uses: actions/checkout@v4
66-
67-
# 2. Download build artifacts
68-
- name: Download APK
81+
- name: Download APK artifact
6982
uses: actions/download-artifact@v4
7083
with:
71-
name: app-release-apks
72-
path: build/app/outputs/bundle/release/
84+
name: apk-release
7385

74-
# 3. Upload to Github Release
75-
- name: Github Release
86+
- name: Deploy to GitHub Release
7687
uses: ncipollo/[email protected]
7788
with:
7889
allowUpdates: true
79-
artifacts: build/app/outputs/bundle/release/*.apk
90+
artifacts: ${{ env.APK_PATH }}
8091
artifactContentType: apk
8192
generateReleaseNotes: true
8293
tag: latest_build
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
name: Translation notifier (post-merge)
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
- dev
8+
paths:
9+
- 'untranslated.txt'
10+
11+
permissions:
12+
contents: read
13+
pull-requests: write
14+
issues: read
15+
16+
jobs:
17+
notify:
18+
runs-on: ubuntu-latest
19+
20+
steps:
21+
- name: Checkout repository
22+
uses: actions/checkout@v4
23+
24+
- name: Resolve merged PR number for this commit
25+
id: pr
26+
uses: actions/github-script@v7
27+
with:
28+
script: |
29+
const commitSha = context.sha;
30+
const prs = await github.rest.repos.listPullRequestsAssociatedWithCommit({
31+
owner: context.repo.owner,
32+
repo: context.repo.repo,
33+
commit_sha: commitSha
34+
});
35+
if (!prs.data.length) {
36+
throw new Error('No PR associated with this commit');
37+
}
38+
core.setOutput('number', prs.data[0].number);
39+
40+
- name: Read untranslated.txt (if present)
41+
id: txt
42+
shell: bash
43+
run: |
44+
FILE="untranslated.txt"
45+
if [ ! -f "$FILE" ]; then
46+
{
47+
echo 'list<<COMMENT_EOF'
48+
echo ''
49+
echo 'COMMENT_EOF'
50+
} >> "$GITHUB_OUTPUT"
51+
exit 0
52+
fi
53+
content="$(cat "$FILE")"
54+
{
55+
echo 'list<<COMMENT_EOF'
56+
printf '%s\n' "$content"
57+
echo 'COMMENT_EOF'
58+
} >> "$GITHUB_OUTPUT"
59+
60+
- name: Fetch translator mapping issue body
61+
id: issue
62+
uses: actions/github-script@v7
63+
env:
64+
ISSUE_NUMBER: "488" # Replace with your mapping issue number
65+
with:
66+
script: |
67+
const issue_number = Number(process.env.ISSUE_NUMBER);
68+
const { data } = await github.rest.issues.get({
69+
owner: context.repo.owner,
70+
repo: context.repo.repo,
71+
issue_number
72+
});
73+
core.setOutput('body', data.body || '');
74+
75+
- name: Map languages to maintainers (code from issue)
76+
id: mapping
77+
uses: actions/github-script@v7
78+
env:
79+
LANGUAGES: ${{ steps.txt.outputs.list }} # content of untranslated.txt
80+
ISSUE_BODY: ${{ steps.issue.outputs.body }} # issue text with "Language (xx) by ..."
81+
TESTING: ${{ vars.TRANSLATION_TESTING || 'false' }} # 'true' to avoid tagging real users
82+
with:
83+
script: |
84+
const body = process.env.ISSUE_BODY || '';
85+
const langPayload = process.env.LANGUAGES || '';
86+
87+
// Parse lines like:
88+
// - English (en) by @user1 @user2
89+
// - Marathi (mr) by @user
90+
// Groups: 1=name, 2=code, 3=handles
91+
const listRegex = /-?\s*([\w\s]+?)\s*\(\s*([a-z]{2,3})\s*\)\s+by\s+(@[A-Za-z0-9_-]+(?:\s+@[A-Za-z0-9_-]+)*)/gi;
92+
93+
const codeToHandles = {};
94+
const codeToName = {};
95+
let match;
96+
while ((match = listRegex.exec(body)) !== null) {
97+
const name = match[1].trim();
98+
const code = match[2].toLowerCase();
99+
const handles = match[3].trim().split(/\s+/);
100+
codeToHandles[code] = handles;
101+
codeToName[code] = name; // use the canonical name from the issue line
102+
}
103+
104+
// Parse untranslated.txt as JSON object keys or newline-separated codes
105+
let untranslatedCodes = [];
106+
try {
107+
const parsed = JSON.parse(langPayload);
108+
untranslatedCodes = Object.keys(parsed).map(k => k.trim().toLowerCase());
109+
} catch {
110+
untranslatedCodes = (langPayload || '')
111+
.split(/\r?\n/)
112+
.map(s => s.trim().toLowerCase())
113+
.filter(Boolean);
114+
}
115+
116+
const testing = (process.env.TESTING || '').toLowerCase() === 'true';
117+
const dummy = '@translation-bot';
118+
const linesCodeOnly = [];
119+
const friendlyLines = [];
120+
121+
for (const code of untranslatedCodes) {
122+
const handles = codeToHandles[code] || [];
123+
const notify = testing && handles.length ? [dummy] : handles;
124+
const fullName = codeToName[code] || code.toUpperCase();
125+
if (notify.length) {
126+
linesCodeOnly.push(`${code}: ${notify.join(' ')}`);
127+
friendlyLines.push(`${fullName} (${code}): ${notify.join(' ')}`);
128+
} else {
129+
linesCodeOnly.push(`${code}: (no maintainer mapped)`);
130+
friendlyLines.push(`${fullName} (${code}): (no maintainer mapped)`);
131+
}
132+
}
133+
134+
core.setOutput('handles', linesCodeOnly.join('\n')); // code-only mapping
135+
core.setOutput('handles_friendly', friendlyLines.join('\n')); // Full Name (code)
136+
137+
- name: Build PR comment body
138+
id: comment
139+
shell: bash
140+
run: |
141+
UNTRANS="${{ steps.txt.outputs.list }}"
142+
HANDLES_FRIENDLY="${{ steps.mapping.outputs.handles_friendly }}"
143+
144+
{
145+
echo 'body<<COMMENT_EOF'
146+
echo '🔔 **Translation Check Notice**'
147+
echo
148+
echo 'The following untranslated language codes were found in `untranslated.txt`:'
149+
echo 'Please translate these keys:'
150+
if [ -n "$UNTRANS" ]; then
151+
echo '```'
152+
printf '%s\n' "$UNTRANS"
153+
echo '```'
154+
else
155+
echo '- No entries found'
156+
fi
157+
echo
158+
echo "📣 Notifying maintainers per language:"
159+
printf '%s\n' "$HANDLES_FRIENDLY"
160+
echo
161+
echo '_Automated post-merge notice by Translation Notifier_'
162+
echo 'COMMENT_EOF'
163+
} >> "$GITHUB_OUTPUT"
164+
165+
- name: Post comment to merged PR
166+
uses: actions/github-script@v7
167+
env:
168+
PR_NUMBER: ${{ steps.pr.outputs.number }}
169+
COMMENT_BODY: ${{ steps.comment.outputs.body }}
170+
with:
171+
script: |
172+
const issueNumber = Number(process.env.PR_NUMBER);
173+
if (!issueNumber || isNaN(issueNumber)) {
174+
throw new Error('PR_NUMBER not set or invalid');
175+
}
176+
const body = process.env.COMMENT_BODY || 'No comment generated.';
177+
await github.rest.issues.createComment({
178+
owner: context.repo.owner,
179+
repo: context.repo.repo,
180+
issue_number: issueNumber,
181+
body
182+
});

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ app.*.map.json
4848
/android/app/debug
4949
/android/app/profile
5050
/android/app/release
51+
/android/build
5152

5253
.vscode/
5354
appwrite

android/app/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ println("PROJECT_ID: $projectId")
5656
release {
5757
// TODO: Add your own signing config for the release build.
5858
// Signing with the debug keys for now, so `flutter run --release` works.
59+
isMinifyEnabled = false
60+
isShrinkResources = false
5961
signingConfig = signingConfigs.getByName("debug")
6062
signingConfig = signingConfigs.getByName("release")
6163
}

android/app/src/main/AndroidManifest.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@
6363
<data android:scheme="appwrite-callback-${PROJECT_ID}" />
6464
</intent-filter>
6565
</activity>
66-
6766

6867

6968
<!-- Don't delete the meta-data below.

0 commit comments

Comments
 (0)