Future of scaffold #245
Replies: 2 comments 1 reply
-
The dream: NixOS but make it windows |
Beta Was this translation helpful? Give feedback.
-
Proposed: Config-in-Repo ArchitectureCore IdeaMove from "run scaffold, then clone project" to "clone project, scaffold discovers config and provisions everything." Config lives in the app repo, versioned alongside code. This solves:
Note The syntax for both approaches below is SUPER under-baked. It's meant to have just enough context to help us align on a direction, after which the details can be ironed out. Approach 1: PowerShell EvolutionKeep the PowerShell foundation, but restructure around reusable modules and declarative config. End-User ExperienceBootstrap (one command does everything): irm https://cdn.yourorg.com/scaffold/bootstrap.ps1 | iex -Args @{
RepoUrl = 'https://github.com/yourorg/retail-kiosk'
InstallDir = "C:\Apps\retail-kiosk"
} Config in repo (retail-kiosk/scaffold.config.ps1): @{
# Include built-in task collections
Include = @(
'scaffold.tasks.dependencies', # Git, Node, MSVC
'scaffold.tasks.kiosk-mode' # All the Windows tweaks
)
Variables = @{
ProjectRoot = C:\Apps\retail-kiosk
UnityVersion = '2023.1.0f1'
}
Tasks = @(
# Built-in modules (idempotent)
@{
Module = 'Package'
Name = 'Install Unity Hub'
Params = @{ Name = 'unityhub'; Ensure = 'Present' }
},
# Custom scripts (extensibility)
'./scripts/install-unity-version.ps1',
# Commands with idempotency
@{
Module = 'Command'
Name = 'Install Dependencies'
Command = 'npm install'
Creates = 'node_modules' # Skips if exists
},
)
} Bootstrap Flow
Pros/ConsPros:
Cons:
Approach 2: Compiled Go ExecutableSingle executable, zero dependencies, declarative YAML config. End-User ExperienceBootstrap: irm https://cdn.yourorg.com/scaffold.exe -OutFile scaffold.exe
.\scaffold.exe bootstrap --repo https://github.com/yourorg/retail-kiosk --install-path C:\Apps\retail-kiosk Config in repo (retail-kiosk/scaffold.yaml): include:
- scaffold.tasks.dependencies
- scaffold.tasks.kiosk-mode
variables:
unity_version: "2023.1.0f1"
tasks:
- module: package
name: Install Unity Hub
package: unityhub
- script: ./scripts/install-unity-version.ps1
- module: command
name: Install Dependencies
command: npm install
creates: node_modules Bootstrap Flow
Pros/ConsPros:
Cons:
The former is like an evolution of the existing logic, the latter is maybe approaching something closer to github-actions syntax. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Capturing some thoughts here that have been bouncing around in a couple slack threads and zoom calls.
Rough Edges
Scaffold could use a glow-up.
It's unclear when to run it.
It installs git, npm, msvc build tools, and other low level dependencies that are required to clone and install a project repo, which makes it seem like you should just go with the standalone installation method and then clone your project. However, the script also wants to schedule a task for your app, which assumes the project is already cloned, and launchpad is being run in that project directory.
Running it multiple times can have side-effects.
like duplicate tasks in task scheduler, repeated registry entries, etc. It would be better if scaffold were more reliably idempotent, so that one could re-run the script to their heart's content. We also have this one related issue that I haven't been able to recreate #16.
It's not extensible.
There are repetetive, scaffold-like tasks that we have to do on multi-instance installations that could easily be scriptable, but there's no way to roll that into the existing scaffold script. Ex: install specific unity engine version and add a license.
It could (should?) do more.
Ideally, we could have a one-line shell command that does everything scaffold already does, plus:
- manage secrets, like cms auth and git tokens
- clone a project repo
- install project dependencies
- build app(s)
Like everything an installation need to get from fresh windows 10 to done. Fixing this fixes the "It's unclear when to run it" issue.
This is kinda dependent on the previous section - extensibility. Not all projects will have the same provisioning needs.
Paths Forward
Some different approaches that could solve some or all of the issues above.
Just more PS1 scripts
We can always just add to the list of PS1 scripts and disable what we don't need. We can make the scripts idempotent by adding checks.
I think the one peculiarity here is how we can achieve extensibility... maybe we allow adding paths to user scripts to be executed?
This also has the benefit of being backwards compatible and easily upgrade-able for legacy projects.
Ansible
We could rebuild scaffold on top of ansible (like how the trellis cli wraps ansible), or scaffold could just become a set of distributed ansible playbooks and roles.
It checks a lot of our boxes: playbooks are extensible, everything is idempotent. There is a large (though shrinking) community.
Ansible is also built around running the same script on multiple hosts from a separate control node, which could really speed up provisioning. Instead of running scaffold on the installation PCs, a developer could specify the targets (accessible via ssh or WinRM), and run the script just once from their dev PC. This isn't required though, ansible can also target the localhost.
Another plus here is ease of deploying updates. Make some code changes that you need to deploy? Just re-run that anisble playbook and it will: pull the code changes, re-build and re-launch the app on all instances.
There is one big downside: as of right now, an ansible control node can't be windows. In the self-target / localhost scenario, this would require installing WSL2, then installing python and other ansible dependencies, then dealing with the awkwardness of targeting the windows node from the linux sub-system... and the list goes on. It effectively just shifts the manual provisioning burden.
Scaffold as an installer
Maybe scaffold just becomes an installer compiler. Write your scaffold config in TS/JS, like the other launchpad configs (extensible!), then compile it to a portable windows installer that can be copied and run anywhere.
There's some awkwardness here with updating the config. It adds the extra step of recompiling the installer, then redistributing.
More to come!
Beta Was this translation helpful? Give feedback.
All reactions