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
1 change: 1 addition & 0 deletions .fallout/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/temp
129 changes: 129 additions & 0 deletions .fallout/build.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"Host": {
"type": "string",
"enum": [
"AppVeyor",
"AzurePipelines",
"Bamboo",
"Bitbucket",
"Bitrise",
"GitHubActions",
"GitLab",
"Jenkins",
"Rider",
"SpaceAutomation",
"TeamCity",
"Terminal",
"TravisCI",
"VisualStudio",
"VSCode"
]
},
"ExecutableTarget": {
"type": "string",
"enum": [
"Bundle",
"Release",
"RestoreValidator",
"ValidateShapes"
]
},
"Verbosity": {
"type": "string",
"description": "",
"enum": [
"Verbose",
"Normal",
"Minimal",
"Quiet"
]
},
"FalloutBuild": {
"properties": {
"Continue": {
"type": "boolean",
"description": "Indicates to continue a previously failed build attempt"
},
"Help": {
"type": "boolean",
"description": "Shows the help text for this build assembly"
},
"Host": {
"description": "Host for execution. Default is 'automatic'",
"$ref": "#/definitions/Host"
},
"NoLogo": {
"type": "boolean",
"description": "Disables displaying the NUKE logo"
},
"Partition": {
"type": "string",
"description": "Partition to use on CI"
},
"Plan": {
"type": "boolean",
"description": "Shows the execution plan (HTML)"
},
"Profile": {
"type": "array",
"description": "Defines the profiles to load",
"items": {
"type": "string"
}
},
"Root": {
"type": "string",
"description": "Root directory during build execution"
},
"Skip": {
"type": "array",
"description": "List of targets to be skipped. Empty list skips all dependencies",
"items": {
"$ref": "#/definitions/ExecutableTarget"
}
},
"Target": {
"type": "array",
"description": "List of targets to be invoked. Default is '{default_target}'",
"items": {
"$ref": "#/definitions/ExecutableTarget"
}
},
"Verbosity": {
"description": "Logging verbosity during build execution. Default is 'Normal'",
"$ref": "#/definitions/Verbosity"
},
"BuildProjectFile": {
"type": [
"null",
"string"
],
"description": "Path to the build project (.csproj) relative to the repository root. Defaults to 'build/_build.csproj' when unset. Read by the Fallout global tool's in-tool runner."
}
}
}
},
"allOf": [
{
"properties": {
"DryRun": {
"type": "boolean",
"description": "Compute, validate and bundle, but do not create the GitHub Release"
},
"ReleaseVersion": {
"type": "string",
"description": "Explicit release version, without the leading 'v' (e.g. 1.4.0). Default: computed from the labels on PRs merged since the last tag"
},
"SchemaRef": {
"type": "string",
"description": "Homelab release tag to pin the portable validator to (default: the moving schema-v1 channel)"
}
}
},
{
"$ref": "#/definitions/FalloutBuild"
}
]
}
3 changes: 3 additions & 0 deletions .fallout/parameters.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$schema": "build.schema.json"
}
45 changes: 45 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: build

# The stack's own PR gate (ADR-0008). Replaces the previous validate.yml, which called the
# superproject's reusable _validate-shapes.yml: the same portable validator runs here, but
# it is now driven by this repo's Fallout build, so `./build.sh` locally and CI run the
# identical target. Also proves the release bundle builds on every PR, rather than finding
# out at release time.
#
# Fallout 10.4 is public on nuget.org, so this needs no package feed credentials.
# SCHEMA_RO_PAT is still required — it downloads the validator from the private
# superproject's schema-v1 release.

on:
pull_request: {}
push:
branches: [main]
workflow_dispatch: {}

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0 # version resolution walks tags + commits back to the last release

- uses: actions/setup-dotnet@v4
with:
global-json-file: global.json

- name: Validate shapes + build the release bundle
env:
SCHEMA_RO_PAT: ${{ secrets.SCHEMA_RO_PAT }} # validator download (private superproject)
GH_TOKEN: ${{ github.token }} # PR-label lookup (this repo)
run: ./build.sh Bundle

- name: Upload the bundle for inspection
uses: actions/upload-artifact@v4
with:
name: devops-bundle
path: dist/
if-no-files-found: error
67 changes: 67 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: release

# Cuts the immutable artifact a deploy consumes. On a merge to main that actually changes
# the deployable stack, the build validates the shapes, bundles them with a manifest, works
# out the next SemVer from the merged PRs' labels, and publishes a GitHub Release.
#
# Why `paths:` and not every main push — the bundle contains shapes and service assets only,
# so a docs-only merge would produce a byte-identical artifact under a new version. Anything
# that changes what gets deployed is listed below; anything else is not a release.
#
# Environment `Production` gates this. Today it records the deployment and is the place to
# hang an approval; a `Test` environment slots in beside it later.

on:
push:
branches: [main]
paths:
- '*.lxc.yaml'
- '*.vm.yaml'
- 'stack.yaml'
- 'aircast/**'
- 'esl2-bridge/**'
- 'leapmotor-mate/**'
- 'matter-server/**'
- 'podman-host/**'
- 'build/**'
- '.github/workflows/release.yml'
workflow_dispatch:
inputs:
version:
description: 'Explicit version without the leading v (e.g. 1.4.0). Blank = compute from PR labels.'
required: false
type: string
dry-run:
description: 'Validate and bundle, but do not create the release.'
required: false
type: boolean
default: false

permissions:
contents: write # create the tag + GitHub Release

concurrency:
group: release
cancel-in-progress: false # never cancel a half-published release

jobs:
release:
runs-on: ubuntu-latest
environment: Production
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0 # version resolution walks tags + commits back to the last release

- uses: actions/setup-dotnet@v4
with:
global-json-file: global.json

- name: Validate, bundle and release
env:
SCHEMA_RO_PAT: ${{ secrets.SCHEMA_RO_PAT }} # validator download (private superproject)
GH_TOKEN: ${{ github.token }} # PR labels + release creation (this repo)
run: |
./build.sh Release \
${{ inputs.version && format('--release-version {0}', inputs.version) || '' }} \
${{ inputs.dry-run && '--dry-run' || '' }}
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Fallout build outputs
build/bin/
build/obj/

# Release bundle + manifest, rebuilt by ./build.sh Bundle
dist/

# Portable validator, downloaded from the superproject's schema-v1 release
.validator/
13 changes: 13 additions & 0 deletions build.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env pwsh
# DevOps stack pipeline entrypoint (Fallout build). Requires the .NET 10 SDK on
# PATH (see global.json) and, for the validator download, a `gh` with read access to
# the private Chrison-Homelab/Homelab repo.
#
# ./build.ps1 # default target: ValidateShapes
# ./build.ps1 Bundle # validate + produce dist/
# ./build.ps1 Release --dry-run # everything except cutting the release
# ./build.ps1 Bundle --skip ValidateShapes # on macOS/Windows (validator is linux-x64)
$ErrorActionPreference = 'Stop'
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
dotnet run --project "$ScriptDir/build/_build.csproj" -- @args
exit $LASTEXITCODE
12 changes: 12 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env bash
# DevOps stack pipeline entrypoint (Fallout build). Requires the .NET 10 SDK on
# PATH (see global.json) and, for the validator download, a `gh` with read access to
# the private Chrison-Homelab/Homelab repo.
#
# ./build.sh # default target: ValidateShapes
# ./build.sh Bundle # validate + produce dist/
# ./build.sh Release --dry-run # everything except cutting the release
# ./build.sh Bundle --skip ValidateShapes # on macOS/Windows (validator is linux-x64)
set -eo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
exec dotnet run --project "$SCRIPT_DIR/build/_build.csproj" -- "$@"
Loading
Loading