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
12 changes: 3 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
node-version: [22, 24]
os: [ubuntu-latest]
runs-on: ${{matrix.os}}
timeout-minutes: 10
timeout-minutes: 20
steps:
- name: Checkout
uses: actions/checkout@v4
Expand All @@ -25,13 +25,7 @@ jobs:
uses: pnpm/action-setup@v4
with:
version: latest
- name: Set private package config
run: pnpm config set '//registry.npmjs.org/:_authToken' "${NODE_AUTH_TOKEN}"
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
- name: Install dependencies
run: pnpm install
- name: Lint
run: pnpm run lint
run: pnpm install --frozen-lockfile
- name: Run Tests
run: pnpm run test
run: pnpm run ci
54 changes: 54 additions & 0 deletions .github/workflows/publish-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Publish release

on:
workflow_dispatch:
inputs:
version:
description: "The version number to tag and release"
required: true
type: string
prerelease:
description: "Release as pre-release"
required: false
type: boolean
default: false

jobs:
release-npm:
runs-on: ubuntu-latest
environment: main
permissions:
contents: write
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Use supported Node.js Version
uses: actions/setup-node@v4
with:
node-version: 22
- name: Restore cached dependencies
uses: actions/cache@v4
with:
path: ~/.pnpm-store
key: node-modules-${{ hashFiles('package.json') }}
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: latest
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Bump version and push commit
run: |
pnpm version ${{ inputs.version }} --no-git-tag-version
git config --global user.name "${{ github.actor }}"
git config --global user.email "${{ github.actor }}@users.noreply.github.com"
git commit -a -m "Bumped v${{ inputs.version }}"
git push origin HEAD:${{ github.ref }}
- name: Publish new version
run: |
npm install npm -g
npm publish --access public --tag ${{ inputs.prerelease == true && 'next' || 'latest' }}
- name: Create release notes
run: |
npx @matteo.collina/release-notes -a ${{ secrets.GITHUB_TOKEN }} -t v${{ inputs.version }} -r ${{ github.repository }} ${{ github.event.inputs.prerelease == 'true' && '-p' || '' }} -c ${{ github.ref }}
53 changes: 15 additions & 38 deletions config.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,32 +164,14 @@ export interface PlatformaticPHPConfiguration {
plugins?: {
[k: string]: unknown;
};
metrics?:
| boolean
| {
port?: number | string;
hostname?: string;
endpoint?: string;
server?: "own" | "parent" | "hide";
defaultMetrics?: {
enabled: boolean;
};
auth?: {
username: string;
password: string;
};
labels?: {
[k: string]: string;
};
};
telemetry?: {
enabled?: boolean | string;
/**
* The name of the service. Defaults to the folder name if not specified.
* The name of the application. Defaults to the folder name if not specified.
*/
serviceName: string;
applicationName: string;
/**
* The version of the service (optional)
* The version of the application (optional)
*/
version?: string;
/**
Expand Down Expand Up @@ -271,6 +253,7 @@ export interface PlatformaticPHPConfiguration {
| string;
$schema?: string;
module?: string;
application?: {};
service?: {
openapi?:
| {
Expand Down Expand Up @@ -324,20 +307,12 @@ export interface PlatformaticPHPConfiguration {
};
};
};
clients?: {
serviceId?: string;
name?: string;
type?: "openapi" | "graphql";
path?: string;
schema?: string;
url?: string;
fullResponse?: boolean;
fullRequest?: boolean;
validateResponse?: boolean;
}[];
runtime?: {
preload?: string | string[];
basePath?: string;
services?: {
[k: string]: unknown;
}[];
workers?: number | string;
logger?: {
level: (
Expand Down Expand Up @@ -423,9 +398,10 @@ export interface PlatformaticPHPConfiguration {
};
startTimeout?: number;
restartOnError?: boolean | number;
exitOnUnhandledErrors?: boolean;
gracefulShutdown?: {
runtime: number | string;
service: number | string;
application: number | string;
};
health?: {
enabled?: boolean | string;
Expand All @@ -435,7 +411,7 @@ export interface PlatformaticPHPConfiguration {
maxELU?: number | string;
maxHeapUsed?: number | string;
maxHeapTotal?: number | string;
maxYoungGeneration?: number;
maxYoungGeneration?: number | string;
};
undici?: {
agentOptions?: {
Expand Down Expand Up @@ -544,11 +520,11 @@ export interface PlatformaticPHPConfiguration {
telemetry?: {
enabled?: boolean | string;
/**
* The name of the service. Defaults to the folder name if not specified.
* The name of the application. Defaults to the folder name if not specified.
*/
serviceName: string;
applicationName: string;
/**
* The version of the service (optional)
* The version of the application (optional)
*/
version?: string;
/**
Expand Down Expand Up @@ -624,7 +600,8 @@ export interface PlatformaticPHPConfiguration {
watchDisabled?: boolean;
[k: string]: unknown;
};
serviceTimeout?: number | string;
applicationTimeout?: number | string;
messagingTimeout?: number | string;
env?: {
[k: string]: string;
};
Expand Down
22 changes: 8 additions & 14 deletions lib/generator.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Generator as ServiceGenerator } from '@platformatic/service'
import { readFile } from 'node:fs/promises'
import { resolve, join } from 'node:path'
import { join } from 'node:path'
import { packageJson } from '../lib/schema.js'

export class Generator extends ServiceGenerator {
constructor (opts = {}) {
Expand Down Expand Up @@ -31,14 +32,13 @@ export class Generator extends ServiceGenerator {
}

async _getConfigFileContents () {
const packageJson = await this._getStackablePackageJson()
const { server, watch } = await super._getConfigFileContents()

return {
$schema: `https://schemas.platformatic.dev/@platformatic/php/${packageJson.version}.json`,
module: `${packageJson.name}`,
php: {
docroot: 'public',
docroot: 'public'
},
server,
watch
Expand All @@ -51,8 +51,6 @@ export class Generator extends ServiceGenerator {
delete this.config.env.PLT_TYPESCRIPT
delete this.config.defaultEnv.PLT_TYPESCRIPT

const packageJson = await this._getStackablePackageJson()

this.config.dependencies = {
[packageJson.name]: `^${packageJson.version}`
}
Expand All @@ -63,15 +61,11 @@ export class Generator extends ServiceGenerator {
delete this.files['.gitignore']

if (!this.config.isUpdating) {
this.addFile({ path: 'public', file: 'index.php', contents: await readFile(join(import.meta.dirname, 'index.php'), 'utf-8') })
this.addFile({
path: 'public',
file: 'index.php',
contents: await readFile(join(import.meta.dirname, 'index.php'), 'utf-8')
})
}
}

async _getStackablePackageJson () {
if (!this._packageJson) {
this._packageJson = JSON.parse(await readFile(resolve(import.meta.dirname, '../package.json'), 'utf-8'))
}

return this._packageJson
}
}
40 changes: 13 additions & 27 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,19 @@
import { buildStackable } from '@platformatic/service'
import { Generator as _Generator } from './generator.js'
import { create as createService, platformaticService } from '@platformatic/service'
import { plugin } from './plugin.js'
import { packageJson, schema } from './schema.js'
import { schema } from './schema.js'

export async function stackable (fastify, opts) {
await fastify.register(plugin, opts)
export async function php (app, capability) {
await platformaticService(app, capability)
await app.register(plugin, capability)
}

stackable.Generator = _Generator
stackable.configType = 'php'
stackable.schema = schema
stackable.configManagerConfig = {
schemaOptions: {
useDefaults: true,
coerceTypes: true,
allErrors: true,
strict: false
}
export async function create (configOrRoot, sourceOrConfig, context) {
return createService(configOrRoot, sourceOrConfig, {
schema,
applicationFactory: php,
...context
})
}

export const Generator = _Generator

export default {
configType: 'php',
configManagerConfig: stackable.configManagerConfig,
/* c8 ignore next 3 */
async buildStackable (opts) {
return buildStackable(opts, stackable)
},
schema,
version: packageJson.version
}
export { Generator } from './generator.js'
export { packageJson, schema, schemaComponents, version } from './schema.js'
20 changes: 12 additions & 8 deletions lib/plugin.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import fp from 'fastify-plugin'

const HTTP_METHODS = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'TRACE']

const capitalizeHeaders = header => header.replace(/(^|-)([a-z])/g, (_, dash, letter) => dash + letter.toUpperCase())

export async function plugin (server, opts) {
// A full URL string is needed for PHP, but Node.js splits that across a bunch of places.
function urlForRequest (req) {
const proto = req.raw.protocol ?? 'http:'
const host = req.headers.host ?? 'localhost'
return new URL(req.url, `${proto}//${host}`)
}

export async function phpPlugin (server, opts) {
// We import this dynically to provide better error reporting in case
// this module fails to load one of the native bindings
const { Php, Request, Rewriter } = await import('@platformatic/php-node')
Expand Down Expand Up @@ -61,7 +70,7 @@ export async function plugin (server, opts) {
method: req.method,
url: url.href,
headers,
body: req.body,
body: req.body
}

const phpReq = new Request(reqInput)
Expand Down Expand Up @@ -97,9 +106,4 @@ export async function plugin (server, opts) {
}
}

// A full URL string is needed for PHP, but Node.js splits that across a bunch of places.
function urlForRequest (req) {
const proto = req.raw.protocol ?? 'http:'
const host = req.headers.host ?? 'localhost'
return new URL(req.url, `${proto}//${host}`)
}
export const plugin = fp(phpPlugin)
Loading