Skip to content

Commit 951c274

Browse files
Copilotnielsdrost7
andcommitted
Add production release workflow with Crowdin integration
Co-authored-by: nielsdrost7 <47660417+nielsdrost7@users.noreply.github.com>
1 parent ac0b0cb commit 951c274

File tree

2 files changed

+331
-0
lines changed

2 files changed

+331
-0
lines changed

.github/workflows/README.md

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
# GitHub Actions Workflows
2+
3+
This directory contains GitHub Actions workflows for automated CI/CD tasks.
4+
5+
## Available Workflows
6+
7+
### 1. Production Release (`release.yml`)
8+
9+
**Trigger:** Automatically runs on every push to the `master` branch
10+
11+
**Purpose:** Creates a production-ready release package of InvoicePlane v2
12+
13+
**What it does:**
14+
1. **Downloads translations from Crowdin** - Retrieves the latest translations
15+
2. **Builds frontend assets** - Runs `yarn install --frozen-lockfile && yarn build`
16+
3. **Installs PHP dependencies** - Runs `composer install --no-dev` for production
17+
4. **Cleans up node_modules** - Removes Node.js dependencies
18+
5. **Optimizes vendor directory** - Removes unnecessary files (tests, docs, etc.)
19+
6. **Creates release archive** - Packages everything into a timestamped ZIP file
20+
7. **Uploads artifact** - Makes the release available for download (90-day retention)
21+
22+
**Required Secrets:**
23+
24+
Before using this workflow, you need to configure these GitHub secrets:
25+
26+
- `CROWDIN_PROJECT_ID` - Your Crowdin project ID
27+
- `CROWDIN_PERSONAL_TOKEN` - Your Crowdin personal access token
28+
29+
To add these secrets:
30+
1. Go to your repository Settings
31+
2. Navigate to Secrets and variables → Actions
32+
3. Click "New repository secret"
33+
4. Add each secret with its corresponding value
34+
35+
**Crowdin Setup:**
36+
37+
To get your Crowdin credentials:
38+
1. Log in to [Crowdin](https://crowdin.com/)
39+
2. Navigate to your InvoicePlane project
40+
3. Go to Settings → API
41+
4. Generate a Personal Access Token
42+
5. Copy your Project ID from the project settings
43+
44+
**Accessing Release Artifacts:**
45+
46+
After the workflow runs:
47+
1. Go to the Actions tab in your repository
48+
2. Click on the completed "Build Production Release" workflow run
49+
3. Scroll down to the "Artifacts" section
50+
4. Download the ZIP file (named `invoiceplane-v2-YYYYMMDD_HHMMSS.zip`)
51+
52+
**Optional: Automatic GitHub Releases**
53+
54+
The workflow includes commented-out code for creating GitHub releases.
55+
To enable automatic releases when you create a tag:
56+
57+
1. Uncomment lines 140-146 in `release.yml`
58+
2. Create and push a tag:
59+
```bash
60+
git tag v2.0.0
61+
git push origin v2.0.0
62+
```
63+
3. The workflow will create a GitHub Release with the ZIP file attached
64+
65+
### 2. PHPUnit Tests (`phpunit.yml`)
66+
67+
**Trigger:** Manual dispatch only
68+
69+
Runs the PHPUnit test suite against a MySQL database.
70+
71+
### 3. Laravel Pint (`pint.yml`)
72+
73+
**Trigger:** Manual dispatch only
74+
75+
Runs Laravel Pint for code formatting checks.
76+
77+
### 4. PHPStan (`phpstan.yml`)
78+
79+
**Trigger:** Manual dispatch only
80+
81+
Runs PHPStan static analysis.
82+
83+
### 5. Docker Compose Check (`docker.yml`)
84+
85+
**Trigger:** Manual dispatch only
86+
87+
Tests Docker Compose configuration.
88+
89+
### 6. Quickstart (`quickstart.yml`)
90+
91+
**Trigger:** Manual dispatch only
92+
93+
Provides a quick setup for development environments.
94+
95+
## Workflow Optimization
96+
97+
### Vendor Directory Cleanup
98+
99+
The release workflow aggressively cleans the vendor directory to minimize file size:
100+
101+
- Removes all test directories (`tests`, `Tests`, `test`, `Test`)
102+
- Removes all documentation (`docs`, `doc`, `*.md`, `*.txt`)
103+
- Removes all Git metadata (`.git`, `.gitignore`, `.gitattributes`)
104+
- Removes build files (`composer.json`, `composer.lock`, `phpunit.xml`, etc.)
105+
- Removes code quality files (`.php_cs`, `phpstan.neon`, etc.)
106+
107+
This typically reduces the vendor directory size by 40-60%.
108+
109+
### ZIP Exclusions
110+
111+
The following files and directories are excluded from the release archive:
112+
113+
- Development files: `.github/*`, `tests/*`, `README.md`
114+
- Configuration files: `phpunit.xml`, `phpstan.neon`, `pint.json`, `rector.php`
115+
- Build tools: `package.json`, `yarn.lock`, `vite.config.js`, `tailwind.config.js`
116+
- Docker files: `docker-compose.yml`
117+
- Environment files: `.env*`
118+
- Storage: `storage/logs/*`, `storage/framework/cache/*`
119+
- Node modules: `node_modules/*` (already removed in cleanup step)
120+
121+
## Troubleshooting
122+
123+
### Crowdin Download Fails
124+
125+
If the Crowdin step fails, check:
126+
1. Secrets are correctly configured
127+
2. Your Crowdin personal token has not expired
128+
3. The project ID is correct
129+
4. Your Crowdin project is properly configured
130+
131+
### Build Fails
132+
133+
If the frontend build fails:
134+
1. Ensure `package.json` is up to date
135+
2. Check for syntax errors in Vite/Tailwind config
136+
3. Verify all dependencies are correctly specified
137+
138+
### Composer Install Fails
139+
140+
If Composer installation fails:
141+
1. Check `composer.json` for syntax errors
142+
2. Ensure all required PHP extensions are available
143+
3. Verify package versions are compatible
144+
145+
## Customization
146+
147+
### Changing PHP Version
148+
149+
Edit line 49 in `release.yml`:
150+
```yaml
151+
php-version: '8.3' # Change to your desired version
152+
```
153+
154+
### Changing Node.js Version
155+
156+
Edit line 36 in `release.yml`:
157+
```yaml
158+
node-version: '20' # Change to your desired version
159+
```
160+
161+
### Adjusting Artifact Retention
162+
163+
Edit line 137 in `release.yml`:
164+
```yaml
165+
retention-days: 90 # Change to your desired retention period (1-90 days)
166+
```
167+
168+
### Custom ZIP Exclusions
169+
170+
Add or remove exclusions in the "Create release zip" step (lines 102-126).
171+
172+
## Best Practices
173+
174+
1. **Test locally first** - Before relying on the workflow, test the build process locally
175+
2. **Monitor workflow runs** - Check the Actions tab regularly for failures
176+
3. **Keep secrets secure** - Never commit secrets to the repository
177+
4. **Update dependencies** - Keep GitHub Actions and dependencies up to date
178+
5. **Tag releases** - Use semantic versioning for production releases
179+
180+
## Support
181+
182+
For issues or questions about these workflows:
183+
- Create an issue in the repository
184+
- Join the [Community Forums](https://community.invoiceplane.com)
185+
- Visit the [Discord server](https://discord.gg/PPzD2hTrXt)

.github/workflows/release.yml

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
name: Build Production Release
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
8+
jobs:
9+
build-release:
10+
name: Build and Package Production Release
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- name: Checkout repository
15+
uses: actions/checkout@v4
16+
17+
# Step 1: Download translations from Crowdin
18+
- name: Download translations from Crowdin
19+
uses: crowdin/github-action@v2
20+
with:
21+
upload_sources: false
22+
upload_translations: false
23+
download_translations: true
24+
localization_branch_name: master
25+
create_pull_request: false
26+
push_translations: false
27+
crowdin_branch_name: master
28+
env:
29+
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
30+
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
31+
32+
# Step 2: Set up Node.js for frontend build
33+
- name: Set up Node.js
34+
uses: actions/setup-node@v4
35+
with:
36+
node-version: '20'
37+
cache: 'yarn'
38+
39+
- name: Install frontend dependencies
40+
run: yarn install --frozen-lockfile
41+
42+
- name: Build frontend assets for production
43+
run: yarn build
44+
45+
# Step 3: Set up PHP and Composer
46+
- name: Set up PHP
47+
uses: shivammathur/setup-php@v2
48+
with:
49+
php-version: '8.3'
50+
extensions: mbstring, bcmath, pdo_mysql
51+
coverage: none
52+
53+
- name: Install Composer dependencies (production)
54+
run: |
55+
composer install --no-dev --optimize-autoloader \
56+
--no-interaction --prefer-dist
57+
58+
# Step 4: Clean up node_modules
59+
- name: Remove node_modules
60+
run: rm -rf node_modules
61+
62+
# Step 5: Clean vendor directory to minimize size
63+
- name: Optimize vendor directory
64+
run: |
65+
# Remove unnecessary files from vendor
66+
find vendor -type d -name "tests" \
67+
-exec rm -rf {} + 2>/dev/null || true
68+
find vendor -type d -name "test" \
69+
-exec rm -rf {} + 2>/dev/null || true
70+
find vendor -type d -name "Tests" \
71+
-exec rm -rf {} + 2>/dev/null || true
72+
find vendor -type d -name "Test" -exec rm -rf {} + 2>/dev/null || true
73+
find vendor -type d -name "docs" -exec rm -rf {} + 2>/dev/null || true
74+
find vendor -type d -name "doc" -exec rm -rf {} + 2>/dev/null || true
75+
find vendor -type d -name ".git" -exec rm -rf {} + 2>/dev/null || true
76+
find vendor -type f -name "*.md" -delete 2>/dev/null || true
77+
find vendor -type f -name "*.txt" -delete 2>/dev/null || true
78+
find vendor -type f -name ".gitignore" -delete 2>/dev/null || true
79+
find vendor -type f -name ".gitattributes" -delete 2>/dev/null || true
80+
find vendor -type f -name "composer.json" -delete 2>/dev/null || true
81+
find vendor -type f -name "composer.lock" -delete 2>/dev/null || true
82+
find vendor -type f -name "phpunit.xml" -delete 2>/dev/null || true
83+
find vendor -type f -name "phpunit.xml.dist" \
84+
-delete 2>/dev/null || true
85+
find vendor -type f -name ".php_cs" \
86+
-delete 2>/dev/null || true
87+
find vendor -type f -name ".php_cs.dist" \
88+
-delete 2>/dev/null || true
89+
find vendor -type f -name "phpstan.neon" \
90+
-delete 2>/dev/null || true
91+
find vendor -type f -name "phpstan.neon.dist" \
92+
-delete 2>/dev/null || true
93+
94+
# Step 6: Create release archive
95+
- name: Create release zip
96+
run: |
97+
# Create a timestamp for the release
98+
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
99+
RELEASE_NAME="invoiceplane-v2-${TIMESTAMP}"
100+
101+
# Create zip excluding unnecessary files
102+
zip -r "${RELEASE_NAME}.zip" . \
103+
-x "*.git*" \
104+
-x "node_modules/*" \
105+
-x "tests/*" \
106+
-x ".env*" \
107+
-x "*.sqlite" \
108+
-x "storage/logs/*" \
109+
-x "storage/framework/cache/*" \
110+
-x "storage/framework/sessions/*" \
111+
-x "storage/framework/views/*" \
112+
-x ".phpunit*" \
113+
-x "phpunit.xml" \
114+
-x "phpstan.neon" \
115+
-x "phpstan-baseline.neon" \
116+
-x "pint.json" \
117+
-x "rector.php" \
118+
-x ".editorconfig" \
119+
-x ".prettierrc" \
120+
-x "docker-compose.yml" \
121+
-x "README.md" \
122+
-x ".github/*" \
123+
-x "yarn.lock" \
124+
-x "package.json" \
125+
-x "vite.config.js" \
126+
-x "tailwind.config.js"
127+
128+
echo "RELEASE_NAME=${RELEASE_NAME}" >> $GITHUB_ENV
129+
echo "RELEASE_FILE=${RELEASE_NAME}.zip" >> $GITHUB_ENV
130+
131+
# Step 7: Upload release artifact
132+
- name: Upload release artifact
133+
uses: actions/upload-artifact@v4
134+
with:
135+
name: ${{ env.RELEASE_NAME }}
136+
path: ${{ env.RELEASE_FILE }}
137+
retention-days: 90
138+
139+
# Optional: Create GitHub Release (uncomment if needed)
140+
# - name: Create GitHub Release
141+
# uses: softprops/action-gh-release@v1
142+
# if: startsWith(github.ref, 'refs/tags/')
143+
# with:
144+
# files: ${{ env.RELEASE_FILE }}
145+
# env:
146+
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

0 commit comments

Comments
 (0)