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
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ jobs:
! otool -L amber amber-lsp | grep -F 'openssl@1.1'

- name: Smoke test generated Amber V2 web app
# Exercise the exact framework and asset releases emitted by the template.
# Exercise the exact published framework emitted by the template.
run: scripts/smoke_generated_web.sh ./amber

- name: Upload build artifacts
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/platform-compile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
run: crystal build src/amber_cli.cr --no-debug -o amber

- name: Compile generated Amber V2 web app
# Exercise the exact framework and asset releases emitted by the template.
# Exercise the exact published framework emitted by the template.
run: scripts/smoke_generated_web.sh ./amber

windows-x86-64:
Expand Down Expand Up @@ -58,5 +58,5 @@ jobs:

- name: Compile generated Amber V2 web app
shell: pwsh
# Exercise the exact framework and asset releases emitted by the template.
# Exercise the exact published framework emitted by the template.
run: scripts/smoke_generated_web.ps1 ./amber.exe
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
[![GitHub release](https://img.shields.io/github/release/amberframework/amber_cli.svg)](https://github.com/amberframework/amber_cli/releases)
[![Docs](https://img.shields.io/badge/docs-available-brightgreen.svg)](https://amberframework.github.io/amber_cli/)

Amber CLI is the standalone command-line companion for Amber V2. CLI `2.0.5`
creates the supported Amber `2.0.0-beta.4` ECR web application and includes
Amber CLI is the standalone command-line companion for Amber V2. CLI `2.0.6`
creates the supported Amber `2.0.0-beta.5` ECR web application and includes
development, generator, database, and LSP tooling.

Amber V2 is a beta. The release-gated path is a web application on Apple
Expand Down Expand Up @@ -32,12 +32,12 @@ the `amber_cli` formula.

### Direct release archive

CLI `2.0.5` publishes `darwin-arm64`, `linux-x86_64`, and `linux-arm64`
CLI `2.0.6` publishes `darwin-arm64`, `linux-x86_64`, and `linux-arm64`
archives. Windows x86-64 is compiled in CI but does not yet have a release
archive.

```bash
version=v2.0.5
version=v2.0.6
platform=darwin-arm64
asset="amber_cli-${platform}.tar.gz"

Expand Down Expand Up @@ -70,7 +70,7 @@ or a file under `app/assets/` changes. Open <http://127.0.0.1:3000>.

The web template is deliberately small:

- Amber from `amberframework/amber`, pinned to `2.0.0-beta.4`
- Amber from `amberframework/amber`, pinned to `2.0.0-beta.5`
- ECR views (Slang and Kilt are not supported in Amber V2)
- typed development, test, and production YAML
- branded homepage, controller spec, and fingerprinted CSS, JavaScript, SVG,
Expand Down Expand Up @@ -175,7 +175,7 @@ The release archive includes `amber-lsp`. From an Amber project:
amber setup:lsp
```

See the [LSP setup guide](https://github.com/amberframework/amber/blob/v2.0.0-beta.4/docs/guides/lsp-setup.md).
See the [LSP setup guide](https://github.com/amberframework/amber/blob/v2.0.0-beta.5/docs/guides/lsp-setup.md).

## Contributing

Expand Down
63 changes: 63 additions & 0 deletions RELEASE_NOTES_V2.0.6.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Amber CLI 2.0.6

Amber CLI 2.0.6 is the coordinated generator release for Amber
`2.0.0-beta.5`. Fresh web applications now use the framework's automatically
enforced schema contracts instead of constructing and validating a second
schema object inside each controller action.

## Generate a complete web application

```bash
amber new pet_tracker --type web
cd pet_tracker
shards install
amber assets check
amber generate scaffold Pet name:string:required species:string:required adopted:bool
amber database migrate
crystal spec
amber watch
```

The generated project pins canonical Amber `2.0.0-beta.5`, uses ECR, Grant,
SQLite, Micrate, local front-end assets, and a manifest-backed asset pipeline.

## What changed

- Resource scaffolds bind `PetSchema` automatically to `create` and `update`
and read typed request-local values with `validated_as(PetSchema)`.
- HTML form schemas declare URL-encoded input and return the generated ECR form
with visible field errors and HTTP 422 when a well-formed request is invalid.
- Malformed or unsupported form bodies preserve the framework's explicit 400
or 415 status instead of being flattened into a generic validation error.
- Preview API generators bind the same executable schema contract for JSON
writes while retaining structured JSON failures.
- `amber generate schema` teaches the executable controller declaration as the
primary application path; direct construction remains available for isolated
schema unit tests.
- The Unix and Windows generated-app smoke harnesses can test an exact framework
repository and commit during coordinated development, while normal and
release CI now exercise the published beta emitted by the template.

## Upgrade compatibility

Amber's deprecated `params.validation` API remains functional. Existing Amber
applications can update the framework first, verify their current behavior,
and migrate validation one controller action at a time. CLI 2.0.6 changes new
generators; it does not force an existing application to regenerate its
controllers.

## Release proof

- 412 Amber CLI examples pass.
- Apple Silicon macOS and x86_64 Linux release-style binaries generate, build,
migrate, run, and exercise the complete web application.
- Linux ARM64 and Windows x86_64 compile and run the generated web application
in GitHub Actions.
- The Pet Tracker smoke proves invalid HTML form input returns one HTML
document with status 422 and a visible field error before proving persisted
create and PATCH update behavior.
- Fingerprinted CSS, JavaScript, SVG, and favicon responses retain integrity,
MIME, immutable caching, URL rewriting, and gzip checks.

Windows remains a source-build compatibility path; this release publishes CLI
archives for Apple Silicon macOS, x86_64 Linux, and ARM64 Linux.
8 changes: 4 additions & 4 deletions docs/BETA_WEB_APP.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Amber V2 Beta Web App

This guide is the consumer smoke test for Amber CLI `2.0.5` and Amber
`2.0.0-beta.4`. It is expected to pass on Apple Silicon macOS, x86_64 Linux,
This guide is the consumer smoke test for Amber CLI `2.0.6` and Amber
`2.0.0-beta.5`. It is expected to pass on Apple Silicon macOS, x86_64 Linux,
and ARM64 Linux. Windows x86-64 compilation is checked in CI.

## 1. Verify the toolchain
Expand All @@ -12,7 +12,7 @@ shards --version
amber --version
```

Crystal must be at least 1.20 and earlier than 2.0. Amber CLI must be 2.0.5 or
Crystal must be at least 1.20 and earlier than 2.0. Amber CLI must be 2.0.6 or
newer.

## 2. Generate the web app
Expand All @@ -30,7 +30,7 @@ grep -A2 'amber:' shard.yml
grep -E '^(template|database|model):' .amber.yml
```

The dependency must be `amberframework/amber` version `2.0.0-beta.4`; the
The dependency must be `amberframework/amber` version `2.0.0-beta.5`; the
template must be `ecr`, the database must be `sqlite`, and the model layer must
be `grant`. `shard.yml` must include Grant, Asset Pipeline, and
`crystal-sqlite3`, but it must not include Gemma, Slang, PostgreSQL, or MySQL
Expand Down
8 changes: 4 additions & 4 deletions docs/RELEASE_CHECKLIST.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ Homebrew formula pins CLI archives and checksums.
## 1. Framework prerelease

1. Confirm `shard.yml`, `src/amber/version.cr`, and the changelog all say
`2.0.0-beta.4`.
`2.0.0-beta.5`.
2. Run framework specs and formatting on macOS and Linux.
3. Tag the reviewed `v2-dev` commit as `v2.0.0-beta.4`.
3. Tag the reviewed `v2-dev` commit as `v2.0.0-beta.5`.
4. Publish it as a GitHub prerelease with migration and support-matrix links.

## 2. CLI release

1. Confirm `shard.yml` and `AmberCLI::VERSION` both say `2.0.5`.
1. Confirm `shard.yml` and `AmberCLI::VERSION` both say `2.0.6`.
2. Generate a web app and verify it pins the framework prerelease.
3. Verify the generated app pins the reviewed Asset Pipeline revision and has
no placeholder dependency revisions.
Expand All @@ -27,7 +27,7 @@ Homebrew formula pins CLI archives and checksums.
6. On macOS, reject any binary linked to `openssl@1.1`.
7. Confirm the Windows x86-64 generated app builds in CI. This is a compatibility
check, not a beta release gate.
8. Tag `v2.0.5`, publish the release, and wait for all archives and checksum
8. Tag `v2.0.6`, publish the release, and wait for all archives and checksum
files to upload.

## 3. Homebrew
Expand Down
26 changes: 22 additions & 4 deletions scripts/check_beta_contract.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ set -euo pipefail

shard_version="$(awk '/^version:/ { print $2; exit }' shard.yml)"
cli_version="$(sed -n 's/.*VERSION = "\([^"]*\)".*/\1/p' src/amber_cli.cr | head -1)"
test "$shard_version" = "2.0.5"
test "$shard_version" = "2.0.6"
test "$cli_version" = "$shard_version"

grep -F 'github: amberframework/amber' src/amber_cli/commands/new.cr
grep -F 'version: 2.0.0-beta.4' src/amber_cli/commands/new.cr
grep -F 'version: 2.0.0-beta.5' src/amber_cli/commands/new.cr
grep -F 'template: ecr' src/amber_cli/commands/new.cr
grep -F 'model: grant' src/amber_cli/commands/new.cr
grep -F 'database: #{database}' src/amber_cli/commands/new.cr
Expand All @@ -17,7 +17,7 @@ grep -F 'version: ~> 0.37.0' src/amber_cli/commands/new.cr
grep -F 'github: amberframework/asset_pipeline' src/amber_cli/templates/app/shard.yml.ecr
grep -F 'version: ~> 0.37.0' src/amber_cli/templates/app/shard.yml.ecr
grep -F 'github: amberframework/amber' src/amber_cli/generators/native_app.cr
grep -F 'version: 2.0.0-beta.4' src/amber_cli/generators/native_app.cr
grep -F 'version: 2.0.0-beta.5' src/amber_cli/generators/native_app.cr
grep -F 'version: ~> 0.37.0' src/amber_cli/generators/native_app.cr
if grep -F 'branch:' src/amber_cli/generators/native_app.cr; then
echo "native app template contains a mutable dependency branch" >&2
Expand All @@ -28,6 +28,24 @@ if grep -F 'shards install || true' src/amber_cli/generators/native_app.cr; then
exit 1
fi
grep -F 'github: amberframework/micrate' shard.yml
grep -F 'info " 2. Bind it in a controller: schema :create, #{class_name}Schema"' src/amber_cli/commands/generate.cr
grep -F 'content_type "#{content_type}"' src/amber_cli/commands/generate.cr
grep -F 'schema :create, #{class_name}Schema' src/amber_cli/commands/generate.cr
grep -F 'schema :update, #{class_name}Schema' src/amber_cli/commands/generate.cr
grep -F 'schema = validated_as(#{class_name}Schema)' src/amber_cli/commands/generate.cr
grep -F 'protected def handle_schema_validation_failure(' src/amber_cli/commands/generate.cr
if grep -F '# schema = #{class_name}Schema.new(data)' src/amber_cli/commands/generate.cr; then
echo "schema generator still teaches direct construction as the controller path" >&2
exit 1
fi

grep -F 'scripts/smoke_generated_web.sh ./amber' .github/workflows/release.yml
if grep -R -F 'AMBER_CANDIDATE_FRAMEWORK' .github/workflows; then
echo "CI workflows must test the published framework emitted by the template" >&2
exit 1
fi
grep -F '[string]$FrameworkRepository = "amberframework/amber"' scripts/smoke_generated_web.ps1
grep -F '" github: $FrameworkRepository"' scripts/smoke_generated_web.ps1
test -s src/amber_cli/templates/app/config/database.cr.ecr
test -s src/amber_cli/templates/app/config/assets.cr.ecr
grep -F 'Your new idea' src/amber_cli/commands/new.cr
Expand All @@ -51,7 +69,7 @@ files=(
README.md
RELEASE_NOTES_V2.0.3.md
RELEASE_NOTES_V2.0.4.md
RELEASE_NOTES_V2.0.5.md
RELEASE_NOTES_V2.0.6.md
RELEASE_SETUP.md
.github/ISSUE_TEMPLATE/release-checklist.md
docs/*.md
Expand Down
20 changes: 18 additions & 2 deletions scripts/smoke_generated_web.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ param(
[Parameter(Mandatory = $true, Position = 0)]
[string]$Cli,
[Parameter(Position = 1)]
[string]$FrameworkCommit = ""
[string]$FrameworkCommit = "",
[Parameter(Position = 2)]
[string]$FrameworkRepository = "amberframework/amber"
)

$ErrorActionPreference = "Stop"
Expand Down Expand Up @@ -37,6 +39,12 @@ $amberConfigPath = Join-Path $appPath ".amber.yml"
$manifest = [System.IO.File]::ReadAllText($shardPath)
$amberConfig = [System.IO.File]::ReadAllText($amberConfigPath)

if (-not $manifest.Contains("github: amberframework/amber")) {
throw "Generated shard.yml does not include Amber"
}
if (-not $manifest.Contains("version: 2.0.0-beta.5")) {
throw "Generated shard.yml does not pin the supported Amber beta"
}
if (-not $manifest.Contains("github: crimson-knight/grant")) {
throw "Generated shard.yml does not include Grant"
}
Expand All @@ -54,10 +62,18 @@ if (-not $amberConfig.Contains("database: sqlite") -or -not $amberConfig.Contain
}

if ($FrameworkCommit) {
$releasedFramework = " version: 2.0.0-beta.4"
$releasedRepository = " github: amberframework/amber"
$releasedFramework = " version: 2.0.0-beta.5"
if (-not $manifest.Contains($releasedRepository)) {
throw "Generated shard.yml does not contain the expected Amber repository"
}
if (-not $manifest.Contains($releasedFramework)) {
throw "Generated shard.yml does not contain the expected Amber beta pin"
}
$manifest = $manifest.Replace(
$releasedRepository,
" github: $FrameworkRepository"
)
$manifest = $manifest.Replace(
$releasedFramework,
" commit: $FrameworkCommit"
Expand Down
35 changes: 32 additions & 3 deletions scripts/smoke_generated_web.sh
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
#!/usr/bin/env bash
set -euo pipefail

if [[ $# -lt 1 || $# -gt 2 ]]; then
echo "usage: $0 /path/to/amber [framework-commit]" >&2
if [[ $# -lt 1 || $# -gt 3 ]]; then
echo "usage: $0 /path/to/amber [framework-commit] [framework-repository]" >&2
exit 64
fi

cli_path="$1"
framework_commit="${2:-}"
framework_repository="${3:-amberframework/amber}"
script_dir="$(cd "$(dirname "$0")" && pwd)"
if [[ "$cli_path" != /* ]]; then
cli_path="$(cd "$(dirname "$cli_path")" && pwd)/$(basename "$cli_path")"
Expand All @@ -30,7 +31,7 @@ trap cleanup EXIT
"$cli_path" new "$app_path" --type web --no-deps

grep -F "github: amberframework/amber" "$app_path/shard.yml"
grep -F "version: 2.0.0-beta.4" "$app_path/shard.yml"
grep -F "version: 2.0.0-beta.5" "$app_path/shard.yml"
grep -F "github: crimson-knight/grant" "$app_path/shard.yml"
grep -F "github: amberframework/asset_pipeline" "$app_path/shard.yml"
grep -F "version: ~> 0.37.0" "$app_path/shard.yml"
Expand All @@ -50,6 +51,7 @@ if grep -Eiq 'gemma:|slang' "$app_path/shard.yml" "$app_path/.amber.yml"; then
fi

if [[ -n "$framework_commit" ]]; then
sed -i.bak -E "s# github: amberframework/amber# github: ${framework_repository}#" "$app_path/shard.yml"
sed -i.bak -E "s/ version: 2\.0\.0-beta\.[0-9]+/ commit: ${framework_commit}/" "$app_path/shard.yml"
rm -f "$app_path/shard.yml.bak"
fi
Expand All @@ -74,6 +76,15 @@ grep -F "class Pet < Grant::Base" src/models/pet.cr
grep -F -- "-- +micrate Up" db/migrations/*_create_pets.sql
grep -F -- "-- +micrate Down" db/migrations/*_create_pets.sql
grep -F 'resources "/pets", PetController' config/routes.cr
grep -F 'content_type "application/x-www-form-urlencoded"' src/schemas/pet_schema.cr
grep -F 'schema :create, PetSchema' src/controllers/pet_controller.cr
grep -F 'schema :update, PetSchema' src/controllers/pet_controller.cr
grep -F 'validated_as(PetSchema)' src/controllers/pet_controller.cr
grep -F 'handle_schema_validation_failure' src/controllers/pet_controller.cr
if grep -F 'PetSchema.new(merge_request_data)' src/controllers/pet_controller.cr; then
echo "generated scaffold bypasses Amber's automatic controller contract" >&2
exit 1
fi
grep -F 'render(partial: "_form.ecr")' src/views/pet/new.ecr
grep -F 'hidden_field("_method", "PATCH")' src/views/pet/_form.ecr

Expand Down Expand Up @@ -163,6 +174,24 @@ grep -F 'name="adopted"' "$new_page" | grep -F 'value="true"'
csrf_token="$(sed -n 's/.*name="_csrf" value="\([^"]*\)".*/\1/p' "$new_page" | head -1)"
test -n "$csrf_token"

invalid_page="$smoke_root/invalid-pet.html"
invalid_headers="$smoke_root/invalid-pet-headers.txt"
invalid_status="$(curl --silent --output "$invalid_page" --dump-header "$invalid_headers" --write-out '%{http_code}' \
--cookie "$cookie_jar" --request POST \
--data-urlencode "_csrf=$csrf_token" \
--data-urlencode "name=Missing Species" \
http://127.0.0.1:3210/pets)"
test "$invalid_status" = "422"
grep -i -F "Content-Type: text/html" "$invalid_headers"
test "$(grep -c '<!DOCTYPE html>' "$invalid_page")" -eq 1
grep -F "Please correct the following" "$invalid_page"
grep -F "species:" "$invalid_page"

curl --fail --silent --cookie "$cookie_jar" --cookie-jar "$cookie_jar" \
http://127.0.0.1:3210/pets/new >"$new_page"
csrf_token="$(sed -n 's/.*name="_csrf" value="\([^"]*\)".*/\1/p' "$new_page" | head -1)"
test -n "$csrf_token"

curl --fail --silent --output /dev/null --dump-header "$response_headers" \
--cookie "$cookie_jar" --request POST \
--data-urlencode "_csrf=$csrf_token" \
Expand Down
2 changes: 1 addition & 1 deletion shard.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: amber_cli
version: 2.0.5
version: 2.0.6

authors:
- crimson-knight <crimsonknightstudios@gmail.com>
Expand Down
Loading
Loading