berg-pages 0.1.0-alpha.10
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 +139 -0
- package/LICENSE +183 -0
- package/README.md +117 -0
- package/dist/adapters/local-deploy-execution-ports.d.ts +12 -0
- package/dist/adapters/local-deploy-execution-ports.js +81 -0
- package/dist/adapters/local-environment-probe.d.ts +5 -0
- package/dist/adapters/local-environment-probe.js +54 -0
- package/dist/adapters/local-init-apply-ports.d.ts +10 -0
- package/dist/adapters/local-init-apply-ports.js +47 -0
- package/dist/adapters/local-project-inspector.d.ts +4 -0
- package/dist/adapters/local-project-inspector.js +250 -0
- package/dist/application/contracts/plugins/deploy-mode-plugin.d.ts +20 -0
- package/dist/application/contracts/plugins/deploy-mode-plugin.js +1 -0
- package/dist/application/contracts/plugins/framework-plugin.d.ts +19 -0
- package/dist/application/contracts/plugins/framework-plugin.js +1 -0
- package/dist/application/contracts/ports/environment-probe-port.d.ts +4 -0
- package/dist/application/contracts/ports/environment-probe-port.js +1 -0
- package/dist/application/contracts/ports/project-inspector-port.d.ts +31 -0
- package/dist/application/contracts/ports/project-inspector-port.js +1 -0
- package/dist/application/contracts/project-context.d.ts +6 -0
- package/dist/application/contracts/project-context.js +1 -0
- package/dist/application/index.d.ts +11 -0
- package/dist/application/index.js +11 -0
- package/dist/application/usecases/apply-deploy-plan.d.ts +8 -0
- package/dist/application/usecases/apply-deploy-plan.js +100 -0
- package/dist/application/usecases/apply-init-plan.d.ts +13 -0
- package/dist/application/usecases/apply-init-plan.js +65 -0
- package/dist/application/usecases/build-deploy-plan.d.ts +9 -0
- package/dist/application/usecases/build-deploy-plan.js +350 -0
- package/dist/application/usecases/build-doctor-plan.d.ts +9 -0
- package/dist/application/usecases/build-doctor-plan.js +253 -0
- package/dist/application/usecases/build-init-plan.d.ts +9 -0
- package/dist/application/usecases/build-init-plan.js +153 -0
- package/dist/application/usecases/create-project-context.d.ts +8 -0
- package/dist/application/usecases/create-project-context.js +194 -0
- package/dist/application/usecases/workflow-diagnostics.d.ts +13 -0
- package/dist/application/usecases/workflow-diagnostics.js +216 -0
- package/dist/core/diagnostics/diagnostic.d.ts +11 -0
- package/dist/core/diagnostics/diagnostic.js +1 -0
- package/dist/core/entities/command.d.ts +1 -0
- package/dist/core/entities/command.js +1 -0
- package/dist/core/entities/deploy-mode.d.ts +6 -0
- package/dist/core/entities/deploy-mode.js +1 -0
- package/dist/core/entities/environment.d.ts +16 -0
- package/dist/core/entities/environment.js +1 -0
- package/dist/core/entities/framework.d.ts +8 -0
- package/dist/core/entities/framework.js +1 -0
- package/dist/core/entities/pages-target.d.ts +23 -0
- package/dist/core/entities/pages-target.js +1 -0
- package/dist/core/entities/project.d.ts +48 -0
- package/dist/core/entities/project.js +1 -0
- package/dist/core/index.d.ts +13 -0
- package/dist/core/index.js +13 -0
- package/dist/core/plans/assumption.d.ts +7 -0
- package/dist/core/plans/assumption.js +1 -0
- package/dist/core/plans/build-plan.d.ts +12 -0
- package/dist/core/plans/build-plan.js +1 -0
- package/dist/core/plans/command-plan.d.ts +27 -0
- package/dist/core/plans/command-plan.js +45 -0
- package/dist/core/plans/deploy-plan.d.ts +17 -0
- package/dist/core/plans/deploy-plan.js +1 -0
- package/dist/core/plans/plan-step.d.ts +59 -0
- package/dist/core/plans/plan-step.js +1 -0
- package/dist/core/plans/template-plan.d.ts +11 -0
- package/dist/core/plans/template-plan.js +1 -0
- package/dist/features/deployment-modes/git-pages-deploy-mode-plugin.d.ts +12 -0
- package/dist/features/deployment-modes/git-pages-deploy-mode-plugin.js +49 -0
- package/dist/features/frameworks/astro-framework-plugin.d.ts +36 -0
- package/dist/features/frameworks/astro-framework-plugin.js +97 -0
- package/dist/features/frameworks/static-html-framework-plugin.d.ts +36 -0
- package/dist/features/frameworks/static-html-framework-plugin.js +94 -0
- package/dist/features/frameworks/vite-framework-plugin.d.ts +36 -0
- package/dist/features/frameworks/vite-framework-plugin.js +97 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/interfaces/cli/main.d.ts +2 -0
- package/dist/interfaces/cli/main.js +316 -0
- package/dist/interfaces/cli/render-command-plan.d.ts +2 -0
- package/dist/interfaces/cli/render-command-plan.js +103 -0
- package/docs/BUG-REPORTS.md +52 -0
- package/docs/CANARY.md +117 -0
- package/docs/COMMANDS.md +141 -0
- package/docs/COMPATIBILITY.md +131 -0
- package/docs/DEPLOY-SAFETY.md +113 -0
- package/package.json +53 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
This changelog records released changes only. Unreleased planning and in-progress work belong in the commit history, pull requests, and milestone documents.
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [v0.1.0-alpha.10]
|
|
10
|
+
|
|
11
|
+
CLI clarity and machine-readable diagnostics alpha.
|
|
12
|
+
|
|
13
|
+
- Add M24 output clarity polish for final apply decision summaries.
|
|
14
|
+
- Add M25 JSON output for doctor, init dry-run, and deploy dry-run plans.
|
|
15
|
+
- Add M26 script-friendly exit codes for read-only plans.
|
|
16
|
+
- Add M27 JSON shape snapshots and trimmed command documentation examples.
|
|
17
|
+
- Add M28 safer help and version output for npm-installed CLI usage.
|
|
18
|
+
- Add M29 actionable CLI usage error messages.
|
|
19
|
+
- Add M30 bug report bundle documentation for read-only JSON diagnostics.
|
|
20
|
+
- Add M31 Codeberg/Forgejo issue templates for public alpha feedback.
|
|
21
|
+
- Add M32 pull request template and maintainer release checklist.
|
|
22
|
+
- Add M33 alpha.10 release candidate checklist.
|
|
23
|
+
- Add M34 alpha.10 tarball install release-candidate smoke record.
|
|
24
|
+
|
|
25
|
+
## [v0.1.0-alpha.9]
|
|
26
|
+
|
|
27
|
+
Compatibility diagnostics alpha.
|
|
28
|
+
|
|
29
|
+
- Add M18 public feedback loop findings from published-package testing.
|
|
30
|
+
- Add M19 root static safe publish design scope without implementing root publishing.
|
|
31
|
+
- Add M20 root static deploy dry-run file classification without enabling root publishing.
|
|
32
|
+
- Treat common audio and video files as root static include candidates.
|
|
33
|
+
- Add M21 missing build output guidance for Vite and Astro deploy dry-runs.
|
|
34
|
+
- Add M22 existing workflow classification diagnostics without relaxing blockers.
|
|
35
|
+
- Add M23 tailored next-step guidance for classified existing workflows.
|
|
36
|
+
- No new mutation, deploy apply, or push behavior is added.
|
|
37
|
+
|
|
38
|
+
## [v0.1.0-alpha.8]
|
|
39
|
+
|
|
40
|
+
Compatibility diagnostics for root static repositories.
|
|
41
|
+
|
|
42
|
+
- Add M16 compatibility findings from published-package real-repository testing.
|
|
43
|
+
- Add M17 root static diagnostics for repositories with root `index.html` and no `dist` or `public`.
|
|
44
|
+
- Refuse root static init and deploy dry-runs without planning workflow writes or root publish steps.
|
|
45
|
+
|
|
46
|
+
## [v0.1.0-alpha.7]
|
|
47
|
+
|
|
48
|
+
Compatibility correction for Codeberg repositories named `pages`.
|
|
49
|
+
|
|
50
|
+
- Infer `https://codeberg.org/<owner>/pages.git` as `https://<owner>.codeberg.page/` with base path `/`.
|
|
51
|
+
- Keep other Codeberg repositories on the project-site path `https://<owner>.codeberg.page/<repo>/`.
|
|
52
|
+
- Allow the guarded `git-pages` deploy plan and apply validation to use root `codeberg.page` targets.
|
|
53
|
+
- Keep custom-domain deploy/apply behavior out of scope.
|
|
54
|
+
- Remove accidental runtime dependencies from package metadata before publishing the patch alpha.
|
|
55
|
+
- Publish `berg-pages@0.1.0-alpha.7` to npm with the `alpha` dist-tag.
|
|
56
|
+
|
|
57
|
+
## [v0.1.0-alpha.6]
|
|
58
|
+
|
|
59
|
+
npm alpha package publication for the supported Codeberg Pages path.
|
|
60
|
+
|
|
61
|
+
- Set the package version to `0.1.0-alpha.6`.
|
|
62
|
+
- Remove accidental runtime dependencies and the private package guard.
|
|
63
|
+
- Clarify custom-domain deploy/apply limits in README and release notes.
|
|
64
|
+
- Add M14 npm publish readiness scope and acceptance docs.
|
|
65
|
+
- Verify package name availability, package contents, and tarball-installed CLI execution.
|
|
66
|
+
- Publish `berg-pages@0.1.0-alpha.6` to npm with the `alpha` dist-tag.
|
|
67
|
+
- Document that npm also resolves `latest` to this prerelease while it is the only published version.
|
|
68
|
+
|
|
69
|
+
## [v0.1.0-alpha.5]
|
|
70
|
+
|
|
71
|
+
Compatibility expansion for the existing Codeberg Pages `git-pages` path. No custom-domain deploy/apply behavior is included.
|
|
72
|
+
|
|
73
|
+
- Add M10 plain static site support for existing `dist` or `public` output directories.
|
|
74
|
+
- Add M11 Astro detection, planning, and deploy dry-run support for `dist` output.
|
|
75
|
+
- Add M12 doctor-only diagnostics for root `.domains` custom-domain files.
|
|
76
|
+
|
|
77
|
+
## [v0.1.0-alpha.4]
|
|
78
|
+
|
|
79
|
+
Package artifact hardening only. No deploy/apply behavior changed from `v0.1.0-alpha.3`.
|
|
80
|
+
|
|
81
|
+
- Harden package metadata and package contents for a future npm release.
|
|
82
|
+
- Add M9 package artifact slice and acceptance docs.
|
|
83
|
+
- Validate `npm pack` contents and tarball-installed CLI execution.
|
|
84
|
+
|
|
85
|
+
## [v0.1.0-alpha.3]
|
|
86
|
+
|
|
87
|
+
Tryability release only. No deploy/apply behavior changed from `v0.1.0-alpha.2`.
|
|
88
|
+
|
|
89
|
+
- Add package `bin` metadata so `berg-pages` can be linked as a command.
|
|
90
|
+
- Add a Node shebang to the CLI entrypoint.
|
|
91
|
+
- Document source install, `npm link`, intended future `npx`, supported alpha commands, and alpha limitations.
|
|
92
|
+
- Add M8 install/run slice and acceptance docs.
|
|
93
|
+
- Validate the source checkout path with a fresh-clone smoke test.
|
|
94
|
+
|
|
95
|
+
## [v0.1.0-alpha.2]
|
|
96
|
+
|
|
97
|
+
Post-alpha safety hardening only. No new product features.
|
|
98
|
+
|
|
99
|
+
- Detect all existing Forgejo workflow YAML files before `init --apply` or deploy planning, not only `.forgejo/workflows/pages.yml`.
|
|
100
|
+
- Block generated Pages workflow planning when repositories already have workflows such as `deploy.yml`, `publish.yml`, or another `.forgejo/workflows/*.yml` or `.yaml` file.
|
|
101
|
+
- Keep external testers on the safer workflow-conflict behavior discovered while testing real Vite repos.
|
|
102
|
+
|
|
103
|
+
## [v0.1.0-alpha.1]
|
|
104
|
+
|
|
105
|
+
First alpha for the narrow, canary-proven Codeberg Pages path.
|
|
106
|
+
|
|
107
|
+
Supported path:
|
|
108
|
+
|
|
109
|
+
- Vite/static output in `dist`
|
|
110
|
+
- Codeberg project Pages target
|
|
111
|
+
- `git-pages` deployment mode
|
|
112
|
+
- generated publish branch named `pages`
|
|
113
|
+
- no custom domain
|
|
114
|
+
|
|
115
|
+
Commands:
|
|
116
|
+
|
|
117
|
+
- `doctor`
|
|
118
|
+
- `init --dry-run`
|
|
119
|
+
- `init --apply`
|
|
120
|
+
- `deploy --dry-run`
|
|
121
|
+
- `deploy --apply --confirm-push`
|
|
122
|
+
|
|
123
|
+
Highlights:
|
|
124
|
+
|
|
125
|
+
- Repository scaffold and initial architecture documentation.
|
|
126
|
+
- M2 complete: local-only `doctor` and `init --dry-run` for the Vite to Codeberg Pages `git-pages` path.
|
|
127
|
+
- M3 complete: local-only doctor and dry-run repair diagnostics render suggestions, branch warnings, and workflow conflict checks.
|
|
128
|
+
- M4 complete: local-only `init --apply` writes the planned workflow file for the supported path while refusing blocking diagnostics, differing workflow conflicts, build commands, deploy, push, and publish behavior.
|
|
129
|
+
- M5 complete: `deploy --dry-run` renders publish source, target, branch, remote, and future push operations without mutation.
|
|
130
|
+
- M6 complete: guarded `deploy --apply --confirm-push` reuses the dry-run deploy plan and executes only declared publish steps.
|
|
131
|
+
- M7 complete: disposable Codeberg canary deploy passed for `berg-pages-canary`; see [docs/CANARY.md](docs/CANARY.md).
|
|
132
|
+
|
|
133
|
+
Limitations:
|
|
134
|
+
|
|
135
|
+
- No custom-domain support.
|
|
136
|
+
- No legacy Codeberg Pages v2 behavior.
|
|
137
|
+
- No hosted CI setup beyond workflow file planning.
|
|
138
|
+
- No multi-framework support beyond the current Vite/static-output path.
|
|
139
|
+
- No alpha release package publishing; this is a source/tag checkpoint.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction, and
|
|
10
|
+
distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by the copyright
|
|
13
|
+
owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all other entities
|
|
16
|
+
that control, are controlled by, or are under common control with that entity.
|
|
17
|
+
For the purposes of this definition, "control" means (i) the power, direct or
|
|
18
|
+
indirect, to cause the direction or management of such entity, whether by
|
|
19
|
+
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
20
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
21
|
+
|
|
22
|
+
"You" (or "Your") shall mean an individual or Legal Entity exercising
|
|
23
|
+
permissions granted by this License.
|
|
24
|
+
|
|
25
|
+
"Source" form shall mean the preferred form for making modifications, including
|
|
26
|
+
but not limited to software source code, documentation source, and configuration
|
|
27
|
+
files.
|
|
28
|
+
|
|
29
|
+
"Object" form shall mean any form resulting from mechanical transformation or
|
|
30
|
+
translation of a Source form, including but not limited to compiled object code,
|
|
31
|
+
generated documentation, and conversions to other media types.
|
|
32
|
+
|
|
33
|
+
"Work" shall mean the work of authorship, whether in Source or Object form, made
|
|
34
|
+
available under the License, as indicated by a copyright notice that is included
|
|
35
|
+
in or attached to the work (an example is provided in the Appendix below).
|
|
36
|
+
|
|
37
|
+
"Derivative Works" shall mean any work, whether in Source or Object form, that
|
|
38
|
+
is based on (or derived from) the Work and for which the editorial revisions,
|
|
39
|
+
annotations, elaborations, or other modifications represent, as a whole, an
|
|
40
|
+
original work of authorship. For the purposes of this License, Derivative Works
|
|
41
|
+
shall not include works that remain separable from, or merely link (or bind by
|
|
42
|
+
name) to the interfaces of, the Work and Derivative Works thereof.
|
|
43
|
+
|
|
44
|
+
"Contribution" shall mean any work of authorship, including the original version
|
|
45
|
+
of the Work and any modifications or additions to that Work or Derivative Works
|
|
46
|
+
thereof, that is intentionally submitted to Licensor for inclusion in the Work
|
|
47
|
+
by the copyright owner or by an individual or Legal Entity authorized to submit
|
|
48
|
+
on behalf of the copyright owner. For the purposes of this definition,
|
|
49
|
+
"submitted" means any form of electronic, verbal, or written communication sent
|
|
50
|
+
to the Licensor or its representatives, including but not limited to
|
|
51
|
+
communication on electronic mailing lists, source code control systems, and
|
|
52
|
+
issue tracking systems that are managed by, or on behalf of, the Licensor for
|
|
53
|
+
the purpose of discussing and improving the Work, but excluding communication
|
|
54
|
+
that is conspicuously marked or otherwise designated in writing by the copyright
|
|
55
|
+
owner as "Not a Contribution."
|
|
56
|
+
|
|
57
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
|
|
58
|
+
of whom a Contribution has been received by Licensor and subsequently
|
|
59
|
+
incorporated within the Work.
|
|
60
|
+
|
|
61
|
+
2. Grant of Copyright License. Subject to the terms and conditions of this
|
|
62
|
+
License, each Contributor hereby grants to You a perpetual, worldwide,
|
|
63
|
+
non-exclusive, no-charge, royalty-free, irrevocable copyright license to
|
|
64
|
+
reproduce, prepare Derivative Works of, publicly display, publicly perform,
|
|
65
|
+
sublicense, and distribute the Work and such Derivative Works in Source or
|
|
66
|
+
Object form.
|
|
67
|
+
|
|
68
|
+
3. Grant of Patent License. Subject to the terms and conditions of this License,
|
|
69
|
+
each Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
|
|
70
|
+
no-charge, royalty-free, irrevocable (except as stated in this section) patent
|
|
71
|
+
license to make, have made, use, offer to sell, sell, import, and otherwise
|
|
72
|
+
transfer the Work, where such license applies only to those patent claims
|
|
73
|
+
licensable by such Contributor that are necessarily infringed by their
|
|
74
|
+
Contribution(s) alone or by combination of their Contribution(s) with the Work
|
|
75
|
+
to which such Contribution(s) was submitted. If You institute patent litigation
|
|
76
|
+
against any entity (including a cross-claim or counterclaim in a lawsuit)
|
|
77
|
+
alleging that the Work or a Contribution incorporated within the Work
|
|
78
|
+
constitutes direct or contributory patent infringement, then any patent licenses
|
|
79
|
+
granted to You under this License for that Work shall terminate as of the date
|
|
80
|
+
such litigation is filed.
|
|
81
|
+
|
|
82
|
+
4. Redistribution. You may reproduce and distribute copies of the Work or
|
|
83
|
+
Derivative Works thereof in any medium, with or without modifications, and in
|
|
84
|
+
Source or Object form, provided that You meet the following conditions:
|
|
85
|
+
|
|
86
|
+
(a) You must give any other recipients of the Work or Derivative Works a copy of
|
|
87
|
+
this License; and
|
|
88
|
+
|
|
89
|
+
(b) You must cause any modified files to carry prominent notices stating that
|
|
90
|
+
You changed the files; and
|
|
91
|
+
|
|
92
|
+
(c) You must retain, in the Source form of any Derivative Works that You
|
|
93
|
+
distribute, all copyright, patent, trademark, and attribution notices from the
|
|
94
|
+
Source form of the Work, excluding those notices that do not pertain to any part
|
|
95
|
+
of the Derivative Works; and
|
|
96
|
+
|
|
97
|
+
(d) If the Work includes a "NOTICE" text file as part of its distribution, then
|
|
98
|
+
any Derivative Works that You distribute must include a readable copy of the
|
|
99
|
+
attribution notices contained within such NOTICE file, excluding those notices
|
|
100
|
+
that do not pertain to any part of the Derivative Works, in at least one of the
|
|
101
|
+
following places: within a NOTICE text file distributed as part of the
|
|
102
|
+
Derivative Works; within the Source form or documentation, if provided along
|
|
103
|
+
with the Derivative Works; or, within a display generated by the Derivative
|
|
104
|
+
Works, if and wherever such third-party notices normally appear. The contents of
|
|
105
|
+
the NOTICE file are for informational purposes only and do not modify the
|
|
106
|
+
License. You may add Your own attribution notices within Derivative Works that
|
|
107
|
+
You distribute, alongside or as an addendum to the NOTICE text from the Work,
|
|
108
|
+
provided that such additional attribution notices cannot be construed as
|
|
109
|
+
modifying the License.
|
|
110
|
+
|
|
111
|
+
You may add Your own copyright statement to Your modifications and may provide
|
|
112
|
+
additional or different license terms and conditions for use, reproduction, or
|
|
113
|
+
distribution of Your modifications, or for any such Derivative Works as a whole,
|
|
114
|
+
provided Your use, reproduction, and distribution of the Work otherwise complies
|
|
115
|
+
with the conditions stated in this License.
|
|
116
|
+
|
|
117
|
+
5. Submission of Contributions. Unless You explicitly state otherwise, any
|
|
118
|
+
Contribution intentionally submitted for inclusion in the Work by You to the
|
|
119
|
+
Licensor shall be under the terms and conditions of this License, without any
|
|
120
|
+
additional terms or conditions. Notwithstanding the above, nothing herein shall
|
|
121
|
+
supersede or modify the terms of any separate license agreement you may have
|
|
122
|
+
executed with Licensor regarding such Contributions.
|
|
123
|
+
|
|
124
|
+
6. Trademarks. This License does not grant permission to use the trade names,
|
|
125
|
+
trademarks, service marks, or product names of the Licensor, except as required
|
|
126
|
+
for reasonable and customary use in describing the origin of the Work and
|
|
127
|
+
reproducing the content of the NOTICE file.
|
|
128
|
+
|
|
129
|
+
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in
|
|
130
|
+
writing, Licensor provides the Work (and each Contributor provides its
|
|
131
|
+
Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
132
|
+
KIND, either express or implied, including, without limitation, any warranties
|
|
133
|
+
or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
134
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
135
|
+
appropriateness of using or redistributing the Work and assume any risks
|
|
136
|
+
associated with Your exercise of permissions under this License.
|
|
137
|
+
|
|
138
|
+
8. Limitation of Liability. In no event and under no legal theory, whether in
|
|
139
|
+
tort (including negligence), contract, or otherwise, unless required by
|
|
140
|
+
applicable law (such as deliberate and grossly negligent acts) or agreed to in
|
|
141
|
+
writing, shall any Contributor be liable to You for damages, including any
|
|
142
|
+
direct, indirect, special, incidental, or consequential damages of any
|
|
143
|
+
character arising as a result of this License or out of the use or inability to
|
|
144
|
+
use the Work (including but not limited to damages for loss of goodwill, work
|
|
145
|
+
stoppage, computer failure or malfunction, or any and all other commercial
|
|
146
|
+
damages or losses), even if such Contributor has been advised of the possibility
|
|
147
|
+
of such damages.
|
|
148
|
+
|
|
149
|
+
9. Accepting Warranty or Additional Liability. While redistributing the Work or
|
|
150
|
+
Derivative Works thereof, You may choose to offer, and charge a fee for,
|
|
151
|
+
acceptance of support, warranty, indemnity, or other liability obligations
|
|
152
|
+
and/or rights consistent with this License. However, in accepting such
|
|
153
|
+
obligations, You may act only on Your own behalf and on Your sole
|
|
154
|
+
responsibility, not on behalf of any other Contributor, and only if You agree to
|
|
155
|
+
indemnify, defend, and hold each Contributor harmless for any liability incurred
|
|
156
|
+
by, or claims asserted against, such Contributor by reason of your accepting any
|
|
157
|
+
such warranty or additional liability.
|
|
158
|
+
|
|
159
|
+
END OF TERMS AND CONDITIONS
|
|
160
|
+
|
|
161
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
162
|
+
|
|
163
|
+
To apply the Apache License to your work, attach the following boilerplate
|
|
164
|
+
notice, with the fields enclosed by brackets "[]" replaced with your own
|
|
165
|
+
identifying information. (Don't include the brackets!) The text should be
|
|
166
|
+
enclosed in the appropriate comment syntax for the file format. We also
|
|
167
|
+
recommend that a file or class name and description of purpose be included on
|
|
168
|
+
the same "printed page" as the copyright notice for easier identification within
|
|
169
|
+
third-party archives.
|
|
170
|
+
|
|
171
|
+
Copyright [yyyy] [name of copyright owner]
|
|
172
|
+
|
|
173
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
174
|
+
you may not use this file except in compliance with the License.
|
|
175
|
+
You may obtain a copy of the License at
|
|
176
|
+
|
|
177
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
178
|
+
|
|
179
|
+
Unless required by applicable law or agreed to in writing, software
|
|
180
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
181
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
182
|
+
See the License for the specific language governing permissions and
|
|
183
|
+
limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# berg-pages
|
|
2
|
+
|
|
3
|
+
`berg-pages` is a plan-first CLI for making Codeberg Pages easier to use without hiding the platform underneath.
|
|
4
|
+
|
|
5
|
+
The core idea is simple: inspect the project, explain the intended Codeberg Pages setup, and require an explicit apply or deploy command before anything changes.
|
|
6
|
+
|
|
7
|
+
## Why this exists
|
|
8
|
+
|
|
9
|
+
Codeberg Pages is useful, but the path from "I have a site" to "it is deployed correctly" still depends on hosting mode, domain setup, and repository workflow. `berg-pages` aims to reduce that friction with a small, predictable core and plugins around the edges where platform details change.
|
|
10
|
+
|
|
11
|
+
## Current Status
|
|
12
|
+
|
|
13
|
+
Current release: `v0.1.0-alpha.10`.
|
|
14
|
+
|
|
15
|
+
The alpha path is intentionally narrow:
|
|
16
|
+
|
|
17
|
+
- Vite output in `dist`
|
|
18
|
+
- Astro output in `dist`
|
|
19
|
+
- plain static output in `dist` or `public`
|
|
20
|
+
- Codeberg `codeberg.page` target for project sites and repositories named `pages`
|
|
21
|
+
- `git-pages` deployment mode
|
|
22
|
+
- generated publish branch named `pages`
|
|
23
|
+
- no custom-domain deploy/apply behavior
|
|
24
|
+
|
|
25
|
+
Supported commands:
|
|
26
|
+
|
|
27
|
+
- `berg-pages doctor .`
|
|
28
|
+
- `berg-pages init --dry-run .`
|
|
29
|
+
- `berg-pages init --apply .`
|
|
30
|
+
- `berg-pages deploy --dry-run .`
|
|
31
|
+
- `berg-pages deploy --apply --confirm-push .`
|
|
32
|
+
|
|
33
|
+
Read-only JSON output:
|
|
34
|
+
|
|
35
|
+
- `berg-pages doctor --json .`
|
|
36
|
+
- `berg-pages init --dry-run --json .`
|
|
37
|
+
- `berg-pages deploy --dry-run --json .`
|
|
38
|
+
|
|
39
|
+
JSON output is for read-only plans only. Apply commands reject `--json`. During the alpha line, the JSON shape exposes the current command plan and is not a stable external schema yet. It is useful for bug reports, compatibility checks, and automation experiments.
|
|
40
|
+
|
|
41
|
+
For issue reports, see [docs/BUG-REPORTS.md](docs/BUG-REPORTS.md) before sharing JSON output.
|
|
42
|
+
|
|
43
|
+
Current limitations:
|
|
44
|
+
|
|
45
|
+
- No custom-domain deploy/apply support.
|
|
46
|
+
- No legacy Codeberg Pages v2 behavior.
|
|
47
|
+
- Root `index.html` sites are detected but not publishable yet; use `dist` or `public`.
|
|
48
|
+
- No hosted CI setup beyond workflow file planning.
|
|
49
|
+
- No multi-framework support beyond the current Vite, Astro, and plain static paths.
|
|
50
|
+
- The npm package is published as an alpha. Use the `alpha` dist-tag until a stable release exists.
|
|
51
|
+
|
|
52
|
+
## Quick Start
|
|
53
|
+
|
|
54
|
+
From npm:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
npx berg-pages@alpha doctor .
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
From source:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npm install
|
|
64
|
+
npm run build
|
|
65
|
+
npm link
|
|
66
|
+
berg-pages doctor .
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
During development:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npm run berg -- doctor .
|
|
73
|
+
npm run berg -- init --dry-run .
|
|
74
|
+
npm run berg -- deploy --dry-run .
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Machine-readable dry runs:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
npm run berg -- doctor --json .
|
|
81
|
+
npm run berg -- init --dry-run --json .
|
|
82
|
+
npm run berg -- deploy --dry-run --json .
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Package note:
|
|
86
|
+
|
|
87
|
+
The first npm publication also resolves through `latest` because it is the only published version. Documentation intentionally uses `berg-pages@alpha` so testers opt into the prerelease line explicitly.
|
|
88
|
+
|
|
89
|
+
Before any push-capable deploy, read [docs/DEPLOY-SAFETY.md](docs/DEPLOY-SAFETY.md).
|
|
90
|
+
|
|
91
|
+
Project verification:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
npm run typecheck
|
|
95
|
+
npm run build
|
|
96
|
+
npm test
|
|
97
|
+
npm pack --dry-run
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Documentation Map
|
|
101
|
+
|
|
102
|
+
- [docs/COMPATIBILITY.md](docs/COMPATIBILITY.md): supported project shapes and compatibility expectations
|
|
103
|
+
- [docs/DEPLOY-SAFETY.md](docs/DEPLOY-SAFETY.md): what deploy apply can mutate and how it stays bounded
|
|
104
|
+
- [docs/COMMANDS.md](docs/COMMANDS.md): intended command surface
|
|
105
|
+
- [docs/BUG-REPORTS.md](docs/BUG-REPORTS.md): safe diagnostic bundles for issue reports
|
|
106
|
+
- [docs/DEPLOYMENT-MODES.md](docs/DEPLOYMENT-MODES.md): supported publishing paths
|
|
107
|
+
- [docs/PRINCIPLES.md](docs/PRINCIPLES.md): non-negotiable design rules
|
|
108
|
+
- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md): layers, dependency direction, composition root
|
|
109
|
+
- [docs/PLUGINS.md](docs/PLUGINS.md): plugin boundaries and contracts
|
|
110
|
+
- [docs/MILESTONES.md](docs/MILESTONES.md): milestone-by-milestone scope
|
|
111
|
+
- [docs/RELEASES.md](docs/RELEASES.md): release process and versioning rules
|
|
112
|
+
- [docs/TESTING.md](docs/TESTING.md): testing strategy
|
|
113
|
+
- [docs/adrs](docs/adrs): architecture decision records
|
|
114
|
+
|
|
115
|
+
## Contributing
|
|
116
|
+
|
|
117
|
+
Before opening implementation work, read [CONTRIBUTING.md](CONTRIBUTING.md). For security-related issues, use [SECURITY.md](SECURITY.md).
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { DeployExecutionPorts } from "../application/contracts/plugins/deploy-mode-plugin.js";
|
|
2
|
+
import type { DeleteFileStep, EnsureDirectoryStep, PublishSiteStep, RunCommandStep, WriteFileStep } from "../core/plans/plan-step.js";
|
|
3
|
+
export declare class LocalDeployExecutionPorts implements DeployExecutionPorts {
|
|
4
|
+
private readonly projectRoot;
|
|
5
|
+
constructor(projectRoot: string);
|
|
6
|
+
writeFile(_step: WriteFileStep): Promise<void>;
|
|
7
|
+
deleteFile(_step: DeleteFileStep): Promise<void>;
|
|
8
|
+
ensureDirectory(_step: EnsureDirectoryStep): Promise<void>;
|
|
9
|
+
runCommand(_step: RunCommandStep): Promise<void>;
|
|
10
|
+
publish(step: PublishSiteStep): Promise<void>;
|
|
11
|
+
private resolveInsideProject;
|
|
12
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { cp, mkdtemp, readdir, rm, stat } from "node:fs/promises";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { resolve, sep } from "node:path";
|
|
4
|
+
import { execFile } from "node:child_process";
|
|
5
|
+
import { promisify } from "node:util";
|
|
6
|
+
const execFileAsync = promisify(execFile);
|
|
7
|
+
export class LocalDeployExecutionPorts {
|
|
8
|
+
projectRoot;
|
|
9
|
+
constructor(projectRoot) {
|
|
10
|
+
this.projectRoot = projectRoot;
|
|
11
|
+
}
|
|
12
|
+
async writeFile(_step) {
|
|
13
|
+
throw new Error("Deploy apply does not write files directly.");
|
|
14
|
+
}
|
|
15
|
+
async deleteFile(_step) {
|
|
16
|
+
throw new Error("Deploy apply does not delete files directly.");
|
|
17
|
+
}
|
|
18
|
+
async ensureDirectory(_step) {
|
|
19
|
+
throw new Error("Deploy apply does not create directories directly.");
|
|
20
|
+
}
|
|
21
|
+
async runCommand(_step) {
|
|
22
|
+
throw new Error("Deploy apply does not run arbitrary commands.");
|
|
23
|
+
}
|
|
24
|
+
async publish(step) {
|
|
25
|
+
const sourceDir = this.resolveInsideProject(step.outputDir);
|
|
26
|
+
const sourceStat = await stat(sourceDir);
|
|
27
|
+
if (!sourceStat.isDirectory()) {
|
|
28
|
+
throw new Error(`Publish source is not a directory: ${step.outputDir}`);
|
|
29
|
+
}
|
|
30
|
+
const publishRoot = await mkdtemp(resolve(tmpdir(), "berg-pages-publish-"));
|
|
31
|
+
try {
|
|
32
|
+
await copyDirectoryContents(sourceDir, publishRoot);
|
|
33
|
+
await runGit(["init"], publishRoot);
|
|
34
|
+
await runGit(["checkout", "-B", step.branch], publishRoot);
|
|
35
|
+
await runGit(["add", "--all"], publishRoot);
|
|
36
|
+
await runGit([
|
|
37
|
+
"-c",
|
|
38
|
+
"user.name=berg-pages",
|
|
39
|
+
"-c",
|
|
40
|
+
"user.email=berg-pages@localhost",
|
|
41
|
+
"commit",
|
|
42
|
+
"-m",
|
|
43
|
+
"Deploy Codeberg Pages"
|
|
44
|
+
], publishRoot);
|
|
45
|
+
await runGit(["remote", "add", "origin", step.remote], publishRoot);
|
|
46
|
+
await runGit(["push", ...(step.force ? ["--force"] : []), "origin", `${step.branch}:${step.branch}`], publishRoot);
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
await rm(publishRoot, { recursive: true, force: true });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
resolveInsideProject(path) {
|
|
53
|
+
const root = resolve(this.projectRoot);
|
|
54
|
+
const resolved = resolve(root, path);
|
|
55
|
+
const rootWithSeparator = root.endsWith(sep) ? root : `${root}${sep}`;
|
|
56
|
+
if (resolved !== root && !resolved.startsWith(rootWithSeparator)) {
|
|
57
|
+
throw new Error(`Refusing to access path outside project root: ${path}`);
|
|
58
|
+
}
|
|
59
|
+
return resolved;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async function copyDirectoryContents(sourceDir, destinationDir) {
|
|
63
|
+
const entries = await readdir(sourceDir, { withFileTypes: true });
|
|
64
|
+
for (const entry of entries) {
|
|
65
|
+
await cp(resolve(sourceDir, entry.name), resolve(destinationDir, entry.name), {
|
|
66
|
+
recursive: true,
|
|
67
|
+
force: true,
|
|
68
|
+
errorOnExist: false
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async function runGit(args, cwd) {
|
|
73
|
+
await execFileAsync("git", args, {
|
|
74
|
+
cwd,
|
|
75
|
+
windowsHide: true,
|
|
76
|
+
env: {
|
|
77
|
+
...process.env,
|
|
78
|
+
GIT_TERMINAL_PROMPT: "0"
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { EnvironmentProbePort } from "../application/contracts/ports/environment-probe-port.js";
|
|
2
|
+
import type { EnvironmentSnapshot } from "../core/entities/environment.js";
|
|
3
|
+
export declare class LocalEnvironmentProbe implements EnvironmentProbePort {
|
|
4
|
+
probe(projectRoot: string): Promise<EnvironmentSnapshot>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { platform } from "node:os";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import { promisify } from "node:util";
|
|
5
|
+
const execFileAsync = promisify(execFile);
|
|
6
|
+
export class LocalEnvironmentProbe {
|
|
7
|
+
async probe(projectRoot) {
|
|
8
|
+
const [gitVersion, npmVersion] = await Promise.all([
|
|
9
|
+
readVersion("git", ["--version"]),
|
|
10
|
+
readVersion("npm", ["--version"])
|
|
11
|
+
]);
|
|
12
|
+
return {
|
|
13
|
+
cwd: resolve(projectRoot),
|
|
14
|
+
os: detectOperatingSystem(),
|
|
15
|
+
ci: Boolean(process.env.CI),
|
|
16
|
+
tools: {
|
|
17
|
+
git: toToolAvailability(gitVersion),
|
|
18
|
+
node: {
|
|
19
|
+
available: true,
|
|
20
|
+
version: process.version.replace(/^v/, "")
|
|
21
|
+
},
|
|
22
|
+
npm: toToolAvailability(npmVersion)
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function detectOperatingSystem() {
|
|
28
|
+
switch (platform()) {
|
|
29
|
+
case "win32":
|
|
30
|
+
return "windows";
|
|
31
|
+
case "darwin":
|
|
32
|
+
return "macos";
|
|
33
|
+
case "linux":
|
|
34
|
+
return "linux";
|
|
35
|
+
default:
|
|
36
|
+
return "unknown";
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function toToolAvailability(version) {
|
|
40
|
+
return version
|
|
41
|
+
? { available: true, version }
|
|
42
|
+
: { available: false };
|
|
43
|
+
}
|
|
44
|
+
async function readVersion(executable, args) {
|
|
45
|
+
try {
|
|
46
|
+
const { stdout } = await execFileAsync(executable, args, {
|
|
47
|
+
windowsHide: true
|
|
48
|
+
});
|
|
49
|
+
return stdout.trim().replace(/^[^\d]*/, "");
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { InitApplyPorts } from "../application/usecases/apply-init-plan.js";
|
|
2
|
+
import type { EnsureDirectoryStep, WriteFileStep } from "../core/plans/plan-step.js";
|
|
3
|
+
export declare class LocalInitApplyPorts implements InitApplyPorts {
|
|
4
|
+
private readonly projectRoot;
|
|
5
|
+
constructor(projectRoot: string);
|
|
6
|
+
ensureDirectory(step: EnsureDirectoryStep): Promise<void>;
|
|
7
|
+
writeFile(step: WriteFileStep): Promise<void>;
|
|
8
|
+
verifyFile(step: WriteFileStep): Promise<boolean>;
|
|
9
|
+
private resolveInsideProject;
|
|
10
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, resolve, sep } from "node:path";
|
|
3
|
+
export class LocalInitApplyPorts {
|
|
4
|
+
projectRoot;
|
|
5
|
+
constructor(projectRoot) {
|
|
6
|
+
this.projectRoot = projectRoot;
|
|
7
|
+
}
|
|
8
|
+
async ensureDirectory(step) {
|
|
9
|
+
await mkdir(this.resolveInsideProject(step.path), { recursive: true });
|
|
10
|
+
}
|
|
11
|
+
async writeFile(step) {
|
|
12
|
+
const filePath = this.resolveInsideProject(step.path);
|
|
13
|
+
await mkdir(dirname(filePath), { recursive: true });
|
|
14
|
+
if (step.mode === "create") {
|
|
15
|
+
const existing = await readExistingFile(filePath);
|
|
16
|
+
if (existing === step.content) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (existing !== undefined) {
|
|
20
|
+
throw new Error(`Refusing to overwrite existing file: ${step.path}`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
await writeFile(filePath, step.content, "utf8");
|
|
24
|
+
}
|
|
25
|
+
async verifyFile(step) {
|
|
26
|
+
const filePath = this.resolveInsideProject(step.path);
|
|
27
|
+
const contents = await readExistingFile(filePath);
|
|
28
|
+
return contents === step.content;
|
|
29
|
+
}
|
|
30
|
+
resolveInsideProject(path) {
|
|
31
|
+
const root = resolve(this.projectRoot);
|
|
32
|
+
const resolved = resolve(root, path);
|
|
33
|
+
const rootWithSeparator = root.endsWith(sep) ? root : `${root}${sep}`;
|
|
34
|
+
if (resolved !== root && !resolved.startsWith(rootWithSeparator)) {
|
|
35
|
+
throw new Error(`Refusing to access path outside project root: ${path}`);
|
|
36
|
+
}
|
|
37
|
+
return resolved;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async function readExistingFile(path) {
|
|
41
|
+
try {
|
|
42
|
+
return await readFile(path, "utf8");
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
}
|