Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ name: Create Release
on:
push:
branches:
- master
- main
pull_request:
types: [closed]
branches:
- master
- main

jobs:
create-release:
# Only run when PR is merged or direct push to master
# Only run when PR is merged or direct push to main
if: github.event_name == 'push' || (github.event.pull_request.merged == true)
runs-on: ubuntu-latest

Expand All @@ -32,21 +32,21 @@ jobs:
- name: Check if tag exists
id: check_tag
run: |
if git rev-parse "v${{ steps.get_version.outputs.version }}" >/dev/null 2>&1; then
if git rev-parse "${{ steps.get_version.outputs.version }}" >/dev/null 2>&1; then
echo "exists=true" >> $GITHUB_OUTPUT
echo "Tag v${{ steps.get_version.outputs.version }} already exists"
echo "Tag ${{ steps.get_version.outputs.version }} already exists"
else
echo "exists=false" >> $GITHUB_OUTPUT
echo "Tag v${{ steps.get_version.outputs.version }} does not exist"
echo "Tag ${{ steps.get_version.outputs.version }} does not exist"
fi

- name: Create tag
if: steps.check_tag.outputs.exists == 'false'
run: |
git config user.name github-actions[bot]
git config user.email github-actions[bot]@users.noreply.github.com
git tag -a "v${{ steps.get_version.outputs.version }}" -m "Release version ${{ steps.get_version.outputs.version }}"
git push origin "v${{ steps.get_version.outputs.version }}"
git tag -a "${{ steps.get_version.outputs.version }}" -m "Release version ${{ steps.get_version.outputs.version }}"
git push origin "${{ steps.get_version.outputs.version }}"

- name: Extract changelog for version
id: changelog
Expand Down Expand Up @@ -88,8 +88,8 @@ jobs:
if: steps.check_tag.outputs.exists == 'false'
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ steps.get_version.outputs.version }}
name: v${{ steps.get_version.outputs.version }}
tag_name: ${{ steps.get_version.outputs.version }}
name: ${{ steps.get_version.outputs.version }}
body: |
${{ steps.changelog.outputs.changelog }}
draft: false
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.0.40
0.0.41
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "celarius/spin-framework",
"description": "A super lightweight PHP UI/REST Framework",
"version": "0.0.40",
"version": "0.0.41",
"keywords": [
"php8",
"php-framework",
Expand Down
2 changes: 1 addition & 1 deletion doc/Contributor-Guide/Getting-Started.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ Types: `feat`, `fix`, `docs`, `test`, `refactor`, `perf`, `chore`
7. **Request review** from maintainers
8. **Address feedback** and update PR
9. **Squash commits** before merge if requested
10. **Merge to develop**, then maintainers merge to master
10. **Merge to develop**, then maintainers merge to main

### Code Review Process

Expand Down
2 changes: 1 addition & 1 deletion doc/Contributor-Guide/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ See [Extension-Points.md](Extension-Points.md) for detailed examples.
- Respond to review feedback
- Push updates (don't force-push)
- Wait for approval
- Maintainer merges to develop, then master
- Maintainer merges to develop, then main

## Resources

Expand Down
10 changes: 5 additions & 5 deletions doc/Contributor-Guide/Submitting-Changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ Once approved:
1. **Squash commits** if requested (multiple commits combined)
2. **Merge to develop** via GitHub
3. **Delete feature branch**
4. **Maintainer merges develop → master** periodically
4. **Maintainer merges develop → main** periodically

## Changelog Updates

Expand Down Expand Up @@ -398,15 +398,15 @@ Releases follow semantic versioning: `MAJOR.MINOR.PATCH`

3. **Create release commit**
```bash
git checkout master
git pull origin master
git checkout main
git pull origin main
git commit -am "release: version 0.0.37"
```

4. **Tag release**
```bash
git tag -a v0.0.37 -m "Release version 0.0.37"
git push origin master --tags
git tag -a 0.0.37 -m "Release version 0.0.37"
git push origin main --tags
```

5. **Create GitHub release**
Expand Down
4 changes: 2 additions & 2 deletions doc/Contributor-Guide/Testing-Guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -568,8 +568,8 @@ public function testUserValidation(): void
Tests run automatically via GitHub Actions:

1. **On every push** to branches
2. **On pull requests** to develop/master
3. **Required before merge** to master (checks coverage, failures)
2. **On pull requests** to develop/main
3. **Required before merge** to main (checks coverage, failures)

Verify locally before pushing:

Expand Down
89 changes: 71 additions & 18 deletions doc/Getting-Started/Project-Structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ my-app/
├── src/
│ └── app/
│ ├── Config/
│ │ ├── version.json Application identity (code, name, version)
│ │ ├── config.json Environment-independent config
│ │ ├── config-dev.json Development config
│ │ ├── config-prod.json Production config
Expand Down Expand Up @@ -89,18 +90,46 @@ my-app/

Configuration is environment-based and uses JSON:

### `version.json` (required)

Sets your application's identity. The framework loads this automatically at startup before any other config file:

```json
{
"application": {
"code": "my-app",
"name": "My Application",
"version": "1.0.0"
}
}
```

| Field | Purpose |
|-------|---------|
| `code` | Machine identifier — used as Monolog log channel name and shared-storage path suffix |
| `name` | Human-readable application label |
| `version` | Semver version string |

Access at runtime:

```php
app()->getAppCode(); // "my-app"
app()->getAppName(); // "My Application"
app()->getAppVersion(); // "1.0.0"
```

### `config.json` (shared)
Global settings used across all environments:

```json
{
"app": {
"name": "My App",
"timezone": "UTC",
"charset": "UTF-8"
},
"cache": {
"default": "file"
"application": {
"global": {
"maintenance": false,
"message": "We are in maintenance mode, back shortly",
"timezone": "UTC"
},
"secret": "${env:APPLICATION_SECRET}"
}
}
```
Expand All @@ -110,24 +139,48 @@ Development overrides and specific config:

```json
{
"debug": true,
"logging": {
"level": "DEBUG"
"application": {
"global": {
"maintenance": false,
"message": "We are in maintenance mode, back shortly",
"timezone": "UTC"
},
"secret": "${env:APPLICATION_SECRET}"
},
"database": {
"default": "mysql",
"connections": {
"mysql": {
"host": "localhost",
"database": "myapp_dev",
"username": "${env:DB_USER}",
"password": "${env:DB_PASS}"
"logger": {
"level": "debug",
"driver": "file",
"drivers": {
"file": {
"file_path": "storage/log",
"file_format": "Y-m-d",
"line_format": "[%datetime%] [%channel%] [%level_name%] %message% %context%\n",
"line_datetime": "Y-m-d H:i:s.v e"
}
}
},
"connections": {
"mysql": {
"type": "Pdo",
"driver": "mysql",
"schema": "${env:DB_DATABASE}",
"host": "${env:DB_HOST}",
"port": "${env:DB_PORT}",
"username": "${env:DB_USERNAME}",
"password": "${env:DB_PASSWORD}",
"charset": "UTF8",
"options": {
"ATTR_PERSISTENT": false,
"ATTR_ERRMODE": "ERRMODE_EXCEPTION",
"ATTR_AUTOCOMMIT": false
}
}
}
}
```

> **Logger `line_format` and line endings:** On Linux, Docker, and Unix systems the file driver may not append a newline after each entry. Add `\n` at the end of `line_format` to ensure each log entry ends with a newline. On Windows this is not required but harmless.

### `config-prod.json`
Production settings with hardened defaults.

Expand Down
24 changes: 24 additions & 0 deletions doc/Getting-Started/Quick-Start.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,30 @@ mkdir -p src/app/Config
mkdir public
```

## Set Your Application Identity

Create `src/app/Config/version.json`:

```json
{
"application": {
"code": "my-first-app",
"name": "My First App",
"version": "0.1.0"
}
}
```

The framework loads this file automatically at startup. Access the values at runtime:

```php
app()->getAppCode(); // "my-first-app"
app()->getAppName(); // "My First App"
app()->getAppVersion(); // "0.1.0"
```

> `code` is also used as the Monolog log channel name and storage path identifier.

## Create Your First Controller

Create `src/app/Controllers/WelcomeController.php`:
Expand Down
59 changes: 40 additions & 19 deletions doc/Getting-Started/Your-First-App.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,22 @@ mkdir -p public
mkdir -p storage/logs
```

## Step 0: Set Your Application Identity

Create `src/app/Config/version.json`:

```json
{
"application": {
"code": "task-api",
"name": "Task Management API",
"version": "1.0.0"
}
}
```

The framework loads this file automatically at startup. `code` is used as the Monolog log channel name and storage path identifier. Access the values at runtime via `app()->getAppCode()`, `app()->getAppName()`, and `app()->getAppVersion()`.

## Step 1: Create Your First Controller

Create `src/app/Controllers/TaskController.php`:
Expand Down Expand Up @@ -359,33 +375,38 @@ namespace App;

## Step 5: Create Configuration

Create `src/app/Config/config.json`:
Create `src/app/Config/config-dev.json`:

```json
{
"app": {
"name": "Task API",
"version": "1.0.0",
"timezone": "UTC"
"application": {
"global": {
"maintenance": false,
"message": "We are in maintenance mode, back shortly",
"timezone": "UTC"
},
"secret": "${env:APPLICATION_SECRET}"
},
"logging": {
"default": "monolog",
"level": "INFO"
"logger": {
"level": "debug",
"driver": "file",
"drivers": {
"php": {
"line_format": "[%channel%] [%level_name%] %message% %context%\n",
"line_datetime": "Y-m-d H:i:s.v e"
},
"file": {
"file_path": "storage/log",
"file_format": "Y-m-d",
"line_format": "[%datetime%] [%channel%] [%level_name%] %message% %context%\n",
"line_datetime": "Y-m-d H:i:s.v e"
}
}
}
}
```

Create `src/app/Config/config-dev.json`:

```json
{
"debug": true,
"logging": {
"level": "DEBUG",
"path": "storage/logs/app.log"
}
}
```
> **`line_format` and line endings:** Append `\n` to `line_format` in the `file` driver to ensure each log entry ends with a newline on Linux, Docker, and Unix systems. On Windows this is not required but harmless.

## Step 6: Start the Development Server

Expand Down
Loading
Loading