@i-santos/firestack 1.0.0 → 3.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.0.0-beta.0
4
+
5
+ ### Major Changes
6
+
7
+ - Start Firestack v3 beta with develop/main branch strategy, environment-based workflows, and PR-first release orchestration.
8
+
9
+ Breaking change details:
10
+
11
+ - `develop` becomes the beta/staging branch and `main` becomes the stable/production branch.
12
+ - Release automation is now PR-first by default across both tracks.
13
+ - New staging/production/weekly workflow contracts define environment-scoped execution.
14
+
15
+ ## 2.0.0
16
+
17
+ ### Major Changes
18
+
19
+ - e7ab55f: Rename package scope to `@i-santos` and adopt the Changesets-only release workflow.
20
+
21
+ Breaking change details:
22
+
23
+ - What changed: the package name moved from `@igorsantos-dev/firestack` to `@i-santos/firestack`.
24
+ - Why: align package identity with the standardized personal brand scope and the new release process.
25
+ - How to migrate: update installs/usages from `@igorsantos-dev/firestack` to `@i-santos/firestack` in scripts and docs.
26
+
3
27
  ## Unreleased
4
28
 
5
29
  - `firestack test`: added deterministic Functions env parity for test processes.
package/README.md CHANGED
@@ -4,6 +4,13 @@ CLI para bootstrap e execução de testes/env em projetos Firebase sem copiar sc
4
4
 
5
5
  ## Modelo Híbrido
6
6
 
7
+ Estratégia v3 beta (infra-first):
8
+
9
+ - `release/beta`: trilha beta do pacote.
10
+ - `main`: trilha estável e ambiente `production`.
11
+ - GitHub Actions orquestra gatilhos, aprovações e segredos por ambiente.
12
+ - Firestack define contratos de execução (`firestack env`, `firestack test`).
13
+
7
14
  Comandos principais:
8
15
 
9
16
  ```bash
@@ -24,7 +31,8 @@ npx firestack test --ci --docker --docker-rebuild
24
31
 
25
32
  ### `init`
26
33
 
27
- Cria `firestack.config.json`, `playwright.config.mjs`, `tests/Dockerfile` e `.dockerignore` no projeto alvo.
34
+ Cria `firestack.config.json`, `playwright.config.mjs`, `tests/Dockerfile`, `.dockerignore`,
35
+ workflows base em `.github/workflows/` e docs operacionais em `docs/`.
28
36
  O template organiza tudo de teste em `out/tests/...`:
29
37
 
30
38
  - `out/tests/unit`
@@ -199,14 +207,31 @@ npm run check
199
207
  npm run changeset
200
208
  npm run version-packages
201
209
  npm run release
210
+ npm run beta:enter
211
+ npm run beta:version
212
+ npm run beta:publish
202
213
  ```
203
214
 
204
215
  Fluxo de release:
205
216
 
206
217
  1. Crie um changeset na sua PR (`npm run changeset`).
207
- 2. Faça merge na branch `main`.
218
+ 2. Faça merge na branch alvo do track:
219
+ - `release/beta` para beta/staging.
220
+ - `main` para stable/production.
208
221
  3. O workflow `.github/workflows/release.yml` cria/atualiza a PR `chore: release packages`.
209
- 4. Ao fazer merge dessa PR de release, o publish no npm e executado.
222
+ 4. O publish acontece apenas em commits `chore: release packages` (modelo PR-first).
223
+ 5. Em `release/beta`, o publish usa track beta. Em `main`, usa track estável.
224
+
225
+ ### Workflows de ambiente
226
+
227
+ - Workflows de APP ficam nos templates do pacote:
228
+ - `templates/workflows/staging.yml`
229
+ - `templates/workflows/production.yml`
230
+ - `templates/workflows/weekly-email-observability.yml`
231
+ - `staging.yml` e `production.yml` dos templates incluem deploy Firebase via `firebase deploy`, usando:
232
+ - secret `FIREBASE_SERVICE_ACCOUNT` (JSON)
233
+ - secret `GCLOUD_PROJECT`
234
+ - variable opcional `FIREBASE_DEPLOY_TARGETS` (para `--only`)
210
235
 
211
236
  ### Bootstrap de projeto existente
212
237
 
@@ -221,5 +246,6 @@ npx @i-santos/create-package-starter init --dir .
221
246
  - Configure npm Trusted Publishing para este pacote com:
222
247
  - owner/repo: `i-santos/firestack`
223
248
  - workflow: `.github/workflows/release.yml`
224
- - branch: `main`
225
- - Se `main` for protegida e exigir checks na release PR, configure o secret `CHANGESETS_GH_TOKEN`.
249
+ - branch: `release/beta` (beta) e `main` (stable)
250
+ - Se `release/beta` ou `main` forem protegidas e exigirem checks na release PR, configure os checks obrigatórios.
251
+ - Use GitHub App auth para automações de release (`GH_APP_CLIENT_ID` + `GH_APP_PRIVATE_KEY`).
package/package.json CHANGED
@@ -1,10 +1,14 @@
1
1
  {
2
2
  "name": "@i-santos/firestack",
3
- "version": "1.0.0",
3
+ "version": "3.0.0-beta.0",
4
4
  "description": "Portable DX and testing bootstrap for Node/Firebase projects",
5
5
  "type": "module",
6
6
  "private": false,
7
7
  "license": "UNLICENSED",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/i-santos/firestack"
11
+ },
8
12
  "bin": {
9
13
  "firestack": "bin/firestack.mjs"
10
14
  },
@@ -26,7 +30,12 @@
26
30
  "changeset": "changeset",
27
31
  "version-packages": "changeset version",
28
32
  "release": "npm run check && changeset publish",
29
- "release:ci": "npm run check && npm run version-packages"
33
+ "release:ci": "npm run check && npm run version-packages",
34
+ "beta:enter": "changeset pre enter beta",
35
+ "beta:exit": "changeset pre exit",
36
+ "beta:version": "changeset version",
37
+ "beta:publish": "changeset publish",
38
+ "beta:promote": "npx @i-santos/create-package-starter@1.5.0-beta.13 promote-stable --dir ."
30
39
  },
31
40
  "devDependencies": {
32
41
  "@playwright/test": "^1.58.2",
@@ -7,6 +7,13 @@ const TEMPLATE_CONFIG = join(ROOT, 'templates', 'firestack.config.json');
7
7
  const TEMPLATE_PLAYWRIGHT_CONFIG = join(ROOT, 'templates', 'playwright.config.mjs');
8
8
  const TEMPLATE_DOCKERFILE = join(ROOT, 'templates', 'tests.Dockerfile');
9
9
  const TEMPLATE_DOCKERIGNORE = join(ROOT, 'templates', 'dockerignore');
10
+ const TEMPLATE_WORKFLOW_QUALITY_GATE = join(ROOT, 'templates', 'workflows', 'quality-gate.yml');
11
+ const TEMPLATE_WORKFLOW_STAGING = join(ROOT, 'templates', 'workflows', 'staging.yml');
12
+ const TEMPLATE_WORKFLOW_PRODUCTION = join(ROOT, 'templates', 'workflows', 'production.yml');
13
+ const TEMPLATE_WORKFLOW_WEEKLY = join(ROOT, 'templates', 'workflows', 'weekly-email-observability.yml');
14
+ const TEMPLATE_DOC_TEST_POLICY = join(ROOT, 'templates', 'docs', 'test-policy.md');
15
+ const TEMPLATE_DOC_ENVIRONMENT_SECRETS = join(ROOT, 'templates', 'docs', 'environment-secrets.md');
16
+ const TEMPLATE_DOC_INCIDENT_RUNBOOK = join(ROOT, 'templates', 'docs', 'incident-rollback-runbook.md');
10
17
 
11
18
  function printHelp() {
12
19
  console.log('Usage: firestack init [--target <dir>] [--force] [--dry-run]');
@@ -106,6 +113,25 @@ export function runInit(argv) {
106
113
  { template: TEMPLATE_CONFIG, relativePath: 'firestack.config.json', label: 'firestack.config.json' },
107
114
  { template: TEMPLATE_PLAYWRIGHT_CONFIG, relativePath: 'playwright.config.mjs', label: 'playwright.config.mjs' },
108
115
  { template: TEMPLATE_DOCKERFILE, relativePath: 'tests/Dockerfile', label: 'tests/Dockerfile' },
116
+ { template: TEMPLATE_WORKFLOW_QUALITY_GATE, relativePath: '.github/workflows/quality-gate.yml', label: '.github/workflows/quality-gate.yml' },
117
+ { template: TEMPLATE_WORKFLOW_STAGING, relativePath: '.github/workflows/staging.yml', label: '.github/workflows/staging.yml' },
118
+ { template: TEMPLATE_WORKFLOW_PRODUCTION, relativePath: '.github/workflows/production.yml', label: '.github/workflows/production.yml' },
119
+ {
120
+ template: TEMPLATE_WORKFLOW_WEEKLY,
121
+ relativePath: '.github/workflows/weekly-email-observability.yml',
122
+ label: '.github/workflows/weekly-email-observability.yml'
123
+ },
124
+ { template: TEMPLATE_DOC_TEST_POLICY, relativePath: 'docs/test-policy.md', label: 'docs/test-policy.md' },
125
+ {
126
+ template: TEMPLATE_DOC_ENVIRONMENT_SECRETS,
127
+ relativePath: 'docs/environment-secrets.md',
128
+ label: 'docs/environment-secrets.md'
129
+ },
130
+ {
131
+ template: TEMPLATE_DOC_INCIDENT_RUNBOOK,
132
+ relativePath: 'docs/incident-rollback-runbook.md',
133
+ label: 'docs/incident-rollback-runbook.md'
134
+ },
109
135
  ];
110
136
  let skippedExisting = false;
111
137
 
@@ -0,0 +1,20 @@
1
+ # Environment and Secrets
2
+
3
+ ## Branch Mapping
4
+
5
+ - `develop` -> `staging`
6
+ - `main` -> `production`
7
+
8
+ ## Secret Scope
9
+
10
+ - Keep staging and production secrets isolated.
11
+ - Use GitHub Environments with approval gates for `production`.
12
+
13
+ ## Baseline Variables
14
+
15
+ - `GCLOUD_PROJECT`
16
+ - `E2E_BASE_URL`
17
+ - `BREVO_API_KEY`
18
+ - `MAILOSAUR_API_KEY` or `MAILTRAP_API_TOKEN`
19
+ - `FIREBASE_SERVICE_ACCOUNT` (JSON credential for deploy workflow)
20
+ - `FIREBASE_DEPLOY_TARGETS` (environment variable, optional; ex: `hosting,functions`)
@@ -0,0 +1,19 @@
1
+ # Incident and Rollback Runbook
2
+
3
+ ## Immediate Actions
4
+
5
+ 1. Stop current rollout and freeze merges to `main`.
6
+ 2. Confirm failing workflow, scope, and blast radius.
7
+ 3. Re-run failing checks with verbose logs.
8
+
9
+ ## Rollback
10
+
11
+ 1. Revert the release commit/PR on `main`.
12
+ 2. Trigger production workflow with approved rollback.
13
+ 3. Validate `npx firestack test --ci --profile production`.
14
+
15
+ ## Follow-up
16
+
17
+ 1. Document root cause and timeline.
18
+ 2. Add/adjust tests to prevent recurrence.
19
+ 3. Promote fix from `develop` after staging validation.
@@ -0,0 +1,16 @@
1
+ # Test Policy
2
+
3
+ ## Daily / PR
4
+
5
+ - Run `npx firestack test --ci --profile staging`.
6
+ - Focus on unit + integration in emulator context and low-cost smoke checks.
7
+
8
+ ## Staging Smoke
9
+
10
+ - Run `npx firestack test --staging --profile staging`.
11
+ - Validate provider contract and traceability with low volume.
12
+
13
+ ## Weekly Extended
14
+
15
+ - Run `npx firestack test --staging --full --profile staging`.
16
+ - Enable observability level 3 with bounded polling and message caps.
@@ -1,2 +1,14 @@
1
1
  # Production app environment
2
2
  GCLOUD_PROJECT=prod-your-project
3
+ E2E_BASE_URL=https://app.example.com
4
+ ALLOW_NON_STAGING_E2E=false
5
+
6
+ # Production credentials (approval-gated environment)
7
+ BREVO_API_KEY=
8
+ MAILOSAUR_API_KEY=
9
+ MAILTRAP_API_TOKEN=
10
+
11
+ # Conservative defaults for production checks
12
+ FIRESTACK_EMAIL_OBSERVABILITY_LEVEL=1
13
+ FIRESTACK_EMAIL_POLL_MAX_SECONDS=60
14
+ FIRESTACK_EMAIL_MAX_TEST_MESSAGES=3
@@ -2,3 +2,15 @@
2
2
  GCLOUD_PROJECT=staging-your-project
3
3
  E2E_BASE_URL=https://staging.example.com
4
4
  ALLOW_NON_STAGING_E2E=false
5
+
6
+ # Provider checks (L1/L2) for staging smoke
7
+ BREVO_API_KEY=
8
+
9
+ # Optional observability provider (L3)
10
+ MAILOSAUR_API_KEY=
11
+ MAILTRAP_API_TOKEN=
12
+
13
+ # Weekly extended guardrails
14
+ FIRESTACK_EMAIL_OBSERVABILITY_LEVEL=2
15
+ FIRESTACK_EMAIL_POLL_MAX_SECONDS=90
16
+ FIRESTACK_EMAIL_MAX_TEST_MESSAGES=5
@@ -2,3 +2,11 @@
2
2
  GCLOUD_PROJECT=prod-your-project
3
3
  E2E_BASE_URL=https://app.example.com
4
4
  ALLOW_NON_STAGING_E2E=false
5
+
6
+ # Production checks should stay low volume and approval-gated
7
+ BREVO_API_KEY=
8
+ MAILOSAUR_API_KEY=
9
+ MAILTRAP_API_TOKEN=
10
+ FIRESTACK_EMAIL_OBSERVABILITY_LEVEL=1
11
+ FIRESTACK_EMAIL_POLL_MAX_SECONDS=60
12
+ FIRESTACK_EMAIL_MAX_TEST_MESSAGES=3
@@ -2,7 +2,19 @@
2
2
  GCLOUD_PROJECT=staging-your-project
3
3
  E2E_BASE_URL=https://staging.example.com
4
4
  ALLOW_NON_STAGING_E2E=false
5
+
6
+ # Staging E2E credentials (fixed users are optional)
5
7
  E2E_STAGING_SMOKE_EMAIL=e2e-smoke@example.com
6
8
  E2E_STAGING_SMOKE_PASSWORD=change-me
7
9
  E2E_STAGING_FULL_EMAIL=e2e-full@example.com
8
10
  E2E_STAGING_FULL_PASSWORD=change-me
11
+
12
+ # Email provider checks
13
+ BREVO_API_KEY=
14
+ MAILOSAUR_API_KEY=
15
+ MAILTRAP_API_TOKEN=
16
+
17
+ # Weekly extended guardrails
18
+ FIRESTACK_EMAIL_OBSERVABILITY_LEVEL=2
19
+ FIRESTACK_EMAIL_POLL_MAX_SECONDS=90
20
+ FIRESTACK_EMAIL_MAX_TEST_MESSAGES=5
@@ -84,6 +84,14 @@
84
84
  "E2E_STAGING_SMOKE_PASSWORD",
85
85
  "E2E_STAGING_FULL_EMAIL",
86
86
  "E2E_STAGING_FULL_PASSWORD",
87
+ "MAILHOG_HOST",
88
+ "MAILHOG_PORT",
89
+ "BREVO_API_KEY",
90
+ "MAILOSAUR_API_KEY",
91
+ "MAILTRAP_API_TOKEN",
92
+ "FIRESTACK_EMAIL_OBSERVABILITY_LEVEL",
93
+ "FIRESTACK_EMAIL_POLL_MAX_SECONDS",
94
+ "FIRESTACK_EMAIL_MAX_TEST_MESSAGES",
87
95
  "E2E_APP_CHECK_DEBUG_TOKEN",
88
96
  "FIREBASE_AUTH_EMULATOR_HOST",
89
97
  "FIRESTORE_EMULATOR_HOST",
@@ -0,0 +1,60 @@
1
+ name: Production Deploy + Gate
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ workflow_dispatch:
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ production:
14
+ runs-on: ubuntu-latest
15
+ environment: production
16
+ steps:
17
+ - name: Checkout
18
+ uses: actions/checkout@v4
19
+
20
+ - name: Setup Node.js
21
+ uses: actions/setup-node@v4
22
+ with:
23
+ node-version: 22
24
+ cache: npm
25
+
26
+ - name: Install
27
+ run: npm ci
28
+
29
+ - name: Prepare production env
30
+ run: npx firestack env --production
31
+
32
+ - name: Run production validation
33
+ run: npx firestack test --ci --profile production
34
+
35
+ - name: Authenticate to Google Cloud
36
+ uses: google-github-actions/auth@v2
37
+ with:
38
+ credentials_json: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
39
+
40
+ - name: Setup Cloud SDK
41
+ uses: google-github-actions/setup-gcloud@v2
42
+
43
+ - name: Install Firebase CLI
44
+ run: npm install -g firebase-tools
45
+
46
+ - name: Deploy to Firebase production
47
+ env:
48
+ GCLOUD_PROJECT: ${{ secrets.GCLOUD_PROJECT }}
49
+ FIREBASE_DEPLOY_TARGETS: ${{ vars.FIREBASE_DEPLOY_TARGETS }}
50
+ run: |
51
+ if [ -z "${GCLOUD_PROJECT}" ]; then
52
+ echo "Missing production secret GCLOUD_PROJECT"
53
+ exit 1
54
+ fi
55
+
56
+ if [ -n "${FIREBASE_DEPLOY_TARGETS}" ]; then
57
+ firebase deploy --project "${GCLOUD_PROJECT}" --only "${FIREBASE_DEPLOY_TARGETS}" --non-interactive
58
+ else
59
+ firebase deploy --project "${GCLOUD_PROJECT}" --non-interactive
60
+ fi
@@ -0,0 +1,31 @@
1
+ name: Quality Gate
2
+
3
+ on:
4
+ pull_request:
5
+ branches:
6
+ - develop
7
+ - main
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ quality-gate:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - name: Checkout
17
+ uses: actions/checkout@v4
18
+
19
+ - name: Setup Node.js
20
+ uses: actions/setup-node@v4
21
+ with:
22
+ node-version: 22
23
+ cache: npm
24
+
25
+ - name: Install
26
+ run: npm ci
27
+
28
+ - name: Firestack CI contracts
29
+ run: |
30
+ npx firestack env --staging
31
+ npx firestack test --ci --profile staging
@@ -0,0 +1,60 @@
1
+ name: Staging Deploy + Smoke
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - develop
7
+ workflow_dispatch:
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ staging:
14
+ runs-on: ubuntu-latest
15
+ environment: staging
16
+ steps:
17
+ - name: Checkout
18
+ uses: actions/checkout@v4
19
+
20
+ - name: Setup Node.js
21
+ uses: actions/setup-node@v4
22
+ with:
23
+ node-version: 22
24
+ cache: npm
25
+
26
+ - name: Install
27
+ run: npm ci
28
+
29
+ - name: Prepare staging env
30
+ run: npx firestack env --staging
31
+
32
+ - name: Run staging smoke
33
+ run: npx firestack test --staging --profile staging
34
+
35
+ - name: Authenticate to Google Cloud
36
+ uses: google-github-actions/auth@v2
37
+ with:
38
+ credentials_json: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
39
+
40
+ - name: Setup Cloud SDK
41
+ uses: google-github-actions/setup-gcloud@v2
42
+
43
+ - name: Install Firebase CLI
44
+ run: npm install -g firebase-tools
45
+
46
+ - name: Deploy to Firebase staging
47
+ env:
48
+ GCLOUD_PROJECT: ${{ secrets.GCLOUD_PROJECT }}
49
+ FIREBASE_DEPLOY_TARGETS: ${{ vars.FIREBASE_DEPLOY_TARGETS }}
50
+ run: |
51
+ if [ -z "${GCLOUD_PROJECT}" ]; then
52
+ echo "Missing staging secret GCLOUD_PROJECT"
53
+ exit 1
54
+ fi
55
+
56
+ if [ -n "${FIREBASE_DEPLOY_TARGETS}" ]; then
57
+ firebase deploy --project "${GCLOUD_PROJECT}" --only "${FIREBASE_DEPLOY_TARGETS}" --non-interactive
58
+ else
59
+ firebase deploy --project "${GCLOUD_PROJECT}" --non-interactive
60
+ fi
@@ -0,0 +1,36 @@
1
+ name: Weekly Email Observability
2
+
3
+ on:
4
+ schedule:
5
+ - cron: '0 5 * * 1'
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ weekly-observability:
13
+ runs-on: ubuntu-latest
14
+ environment: staging
15
+ steps:
16
+ - name: Checkout
17
+ uses: actions/checkout@v4
18
+
19
+ - name: Setup Node.js
20
+ uses: actions/setup-node@v4
21
+ with:
22
+ node-version: 22
23
+ cache: npm
24
+
25
+ - name: Install
26
+ run: npm ci
27
+
28
+ - name: Prepare staging env
29
+ run: npx firestack env --staging
30
+
31
+ - name: Run weekly extended path
32
+ env:
33
+ FIRESTACK_EMAIL_OBSERVABILITY_LEVEL: '3'
34
+ FIRESTACK_EMAIL_POLL_MAX_SECONDS: '180'
35
+ FIRESTACK_EMAIL_MAX_TEST_MESSAGES: '10'
36
+ run: npx firestack test --staging --full --profile staging