Tweet
#shipnix launch date tomorrow 😱

βœ… Automated backups when changing environment variables
βœ… Add Plausible analytics
βœ… Automated DB backups to S3 storage
βœ… SEO/OG tags
βœ… Lots of minor fixes

Will do intense testing until late this evening

#buildinpublic
2 days to #shipnix launch

βœ… Finally get to the point where I feel that Shipnix works as I want it to work

Pulled late-nighter and plowed through critical tasks and bugs

Only remains activating Stripe on production and some minor stuff before launch on monday

#buildinpublic
3 days to #shipnix launch

βœ… Improve reliability of error handling by eliminating exceptions on builds
βœ… Make errors stand out for better debugging

Pulling a late-nighter to try to get free time in the weekend so I can just open the gates on monday

#buildinpublic
4 days to #shipnix public launch

βœ… Get mentioned on @HaskelInterlude podcast 😍
βœ… Add logo and adjust color scheme
βœ… Give the landing page some love
βœ… Write a public security policy because I think it will be important for trust by high value customers

#buildinpublic
5 days to NEW launch date of #shipnix

βœ… Get logo from Fiverr logo maker. Not 100% sure yet, but think I like it
βœ… Fix bugs in migration flow, solved by deleting more code than I added πŸ‘Œ
βœ… Let users review and modify environment variables before migration

#buildinpublic
Hi! I'm moving #shipnix release date to monday

This gives me some time to prepare the landing page, do rigorous testing and fix a couple of remaining bugs

I don't think rushing is necessary when a few extra days will make launch a bit smoother

#buildinpublic
*Planned* launch of #shipnix is tomorrow

βœ… Test Stripe integration with 'test clock' to travel in time and trigger events
βœ… Cancellation and failed payments now works as expected πŸŽ‰

It is very likely I will postpone launch to monday. Will decide tomorrow

#buildinpublic
2 days to planned launch of #shipnix

βœ… Touch up UI of server provider credential manager
βœ… Validate that a DigitalOcean access token is valid, or else do not allow updating it
βœ… Make the consequenses of deleting DO credentials very visible and require password

#buildinpublic
3 days to launch of #shipnix

βœ… Fix up Stripe webhook logic for cancellation & failed payments
βœ… Add styling to Billing page
βœ… Use standard Stripe proration instead of "prorate instantly", so switching from annual to monthly won't lead to enormous refund πŸ’Έ

#buildinpublic
βœ… Create self-serviced flow so users can upgrade NixOS image to current version

Only visible for users at 23.05 launch, but was nice opportunity to fix now πŸ™‚

4 days to planned launch of #shipnix

Brain is a bit fried, but I think I should be able to make it 😁

#buildinpublic
5 days to launch of #shipnix

βœ… Move Stripe testing to stage and test cancellation in production-like environment
βœ… Build 22.11 DigitialOcean image and verify creating servers still works
βœ… Make flow to set current supported NixOS version in admin dashboard

#buildinpublic
Another day of working towards the deadline!

βœ… Developed constraints for all tiers
βœ… Make it possible to change plans whenever and get prorated if downgrading plan through Stripe customer portal

6 days to launch of #shipnix and it seems I am on schedule πŸ˜€

#buildinpublic
βœ… Finish first draft of SSH docs for #shipnix

Documenting is hard work, but satisfying πŸ˜„

#buildinpublic
Write more documentation and add syntax highlighting to docs #shipnix #buildinpublic
Nothing quite finished today.

Writing docs and also exploring how to differentiate between staging and a production environment in configuration.nix in a pure way

#shipnix #buildinpublic
βœ… Introduction/get started part of the docs done #shipnix #buildinpublic
βœ… Make an outline for everything I should document befor release. Also build my own doc generator so I can get things my way.

Got tired of looking for doc generators, feel like they all are too heavily engineered, so just made my own with eleventy 😊

#buildinpublic #shipnix
βœ… Add link to roadmap.ship-nix.com I made yesterday in dashboard and landing page.

Otherwise having a chill day today.

Will only and write documentation, and update #shipnix IHP version to 1.0 #buildinpublic
Now colorizing works as expected! The highest ranked feature(s) will always have the darkest green,next highest lightest green etc

It's raw and simple, but a fully functional public roadmap built and shipped in under 24 hours with #shipnix πŸ˜€ A great field test!

#buildinpublic
Replace the very large info box with a paragraph and a link #shipnix #buildinpublic

I do kind of love the humble aesthetics of unpolished Bootstrap πŸ™‚
Make very primitive page view for each feature for more in-depth description #buildinpublic #shipnix
Actually it was too easy to fix the correct ordering, so I couldn't wait πŸ˜„ I guess it's an actual MVP now.

Will just fix it up with a bit of coloring after dinner!

#shipnix #buildinpublic
βœ… Now actual data is shown on the dashboard and DIE score is calculated #shipnix #buildinpublic

Going to fill up with a bit of food first, and later fix the ordering so we can call this a completed MVP withing 24 hoursπŸ™‚
βœ… Push functionality for actually calculating the DIE score and show the actual data on front page github.com/ship-nix/roadm…

#shipnix #buildinpublic
Make conversion functions of enums to ints so they can be calculated.

I guess idiomatic Haskell way would be to use numeric instances, but I found it too much hassle for so little.

So I just made these simple functions.

#buildinpublic #shipnix
Turn enum values very easily into <select> options with `CanSelect` instance. Very little code required in IHP!

I guess enums are a bit frowned upon in some contexts, but they fit really nicely into Haskell/IHP and have not failed me so far.

#buildinpublic #shipnix
Deploy changes and database is automatically migrated #buildinpublic #shipnix
Also add the same environment variables in production, with a bit more challenging credentials #shipnix #buildinpublic
Protect admin application with simple basic auth, since I am the only one creating and editing features.

Set username and password via environment variables so no actual secrets leak into source code.

Locally, simply admin/pass will do fine!

#buildinpublic #shipnix
Add database structure for features

Unsure if I should have gone with integers instead of postgres enums

Decided to try enums first as they will provide better constraints and be better typed in Haskell land

#buildinpublic #shipnix
Generate an Admin application in IHP which is where I will be managing the features #buildinpublic #shipnix
Set `IHP_BASEURL` to domain instead of IP address so app navigation will function properly #buildinpublic #shipnix
βœ… Add roadmap site to uptime.ship-nix.com to track uptime every minute #buildinpublic #shipnix
roadmap.ship-nix.com is live with https enabled πŸŽ‰ Easy! Going to eat now and continue later #buildinpublic #shipnix
Domain seems to have propagated properly, so try enable https via #NixOs declaration github.com/ship-nix/roadm…
#buildinpublic #shipnix
βœ… Simple table with mock data and a description card below to explain the method

Git diff:
github.com/ship-nix/roadm…

#buildinpublic #shipnix
I have decided to give the default Bootstrap 5 shipped with IHP a chance. Haven't touched bootstrap since I first learned web development #buildinpublic #shipnix
I have decided to give the default Bootstrap 5 shipped with IHP a chance. Haven't touched bootstrap since I first learned web development #buildinpublic #shipnix
βœ… Low hanging evening fruit: Load server data instantly into Elm view, so no more loading flickering/layout shift.

Seemlessly hydrates with IHP DataSync realtime data which is really nice because updating state = just subscribing to changes in db row.

#shipnix #buildinpublic
βœ… Delete NixOs custom image automatically when user deletes ship-nix account since hosting custom images costs a couple of cents per month #shipnix #buildinpublic
βœ… Add server-validation to form for adding DigitalOcean credentials, including when DigitalOcean API complains #shipnix #buildinpublic
Make sure #shipnix is still usable for non-github users and that relevant views print correctly #buildinpublic
βœ… Full client-side validation on "New server" form since whole form is in SPA (Elm) land.

Form now only attempts submit if valid (already has server-side validation) #shipnix #buildinpublic

Probably better to later make it a mainly server-rendered form w some SPA form fields
βœ… Add client side error message on server name input so user gets instant feedback #shipnix #buildinpublic
βœ… Fix migration flow so it's more obvious something is loading, move more state into database and "cancel and start fresh" button.

In short, trying to make it intuitive enough for an early adopter.

#shipnix #buildinpublic
βœ… Fixed bug where database is declared twice on IHP starters.

I think automated e2e tests will be great for catching problems early after code changes. High priority after launch. #shipnix #buildinpublic
βœ… Fix deploy key edge case

Can happen when 1st attempt adding repo fails. Later you retry and fail when deploy key was added last build

#shipnix now checks if deploy key for the server is already present before trying to add. Just skips if all is good

#buildinpublic
βœ… Store deploy key information in database when using Github so they can later be deleted when server is destroyed or ejected. And implement this functionality on server deletion.

#shipnix #buildinpublic
βœ…Decide server dashboard layout & features are good enough for public #buildinpublic #shipnix

NEXT STEPS:
- Simplify onboarding and create server flow. Too many steps now.
- Write docs
- Release free open source tier to public
- Hook up Stripe for commercial tiers
βœ… Build staging server by inputting only #shipnix repo and environment variables. Otherwise everything assembled automatically.

Some minutes later, a server identical to #shipnix production with it's own database was reproduced with the power of Nix!

#shipnix #buildinpublic
βœ… Build staging server by inputting only #shipnix repo and environment variables. Otherwise everything assembled automatically.

Some minutes later, a server identical to #shipnix production with it's own database was reproduced with the power of Nix!

#shipnix #buildinpublic
βœ… Build staging server by inputting only #shipnix repo and environment variables. Otherwise everything assembled automatically.

Some minutes later, a server identical to #shipnix production with it's own database was reproduced with the power of Nix!

#shipnix #buildinpublic
βœ… Switch to Network.HTTP.Simple for all Github requests so response parsing and error handling works as expected, and test it still works as it used to #shipnix #buildinpublic
βœ… Rebuild #shipnix staging server I accidentaly deleted.

I discovered several new snags in the migrate flow. Trying to reproduce ship-nix with ship-nix is great dogfooding for manual testing.

Lots of provisioning and destroying servers until it works properly #buildinpublic
βœ… Only set a deploy job to have one attempt so it doesn't automatically retry when it should have failed and the event ended #shipnix #buildinpublic
βœ… Automatically create MINIMUM_REVISION environment variable to posix now when migrating current IHP projects, so old db migrations are not performed #shipnix #buildinpublic
Fix postgres flow so that generated database passwords won't be exposed to source files #shipnix #buildinpublic
Make destroy server modal with mandatory sanity check #shipnix #buildinpublic
Wasted time trying to make a better accessible modals with custom elements that can be called both by Elm and html templates in #shipnix. Turned out to be complicated at low gains.

Typical rabbit hole that makes minor difference for user, but itches the coder ego #buildinpublic
Add discreet tab navigation to server dashboard.

One of the most important reasons is to hide away the "Destroy server" button as this has been to easily available on the front page of the dashboardπŸ’€ #shipnix #buildinpublic
βœ”οΈ Fix bugs where building continues after recieving a failed bash exit code #shipnix #buildinpublic
Working on the core of #shipnix today, fixing tech debt I consider severe enough to be release blockers.

Working on setting some guarantees ensuring that when shell commands fail, build event stops and is set to failed, and doesn't continue by accident #buildinpublic