Sorry, you need to enable JavaScript to visit this website.

PHP

An economic regulator's website, migrated without losing the record

When the website is the public record: a regulator's statutory publication channel

The organisation behind these websites is a state economic regulator. Its work is public and procedural:

  • it sets the maximum prices people pay for essential services
  • it licenses some of the utilities that provide them
  • it runs formal public reviews with consultation periods, submissions and hearings

Its website is not a brochure. It is the regulator's statutory publication channel, and a determination is published at the moment it appears there.

The organisations it regulates, and the lawyers who advise them, cite that site, and those citations are expected to keep resolving for years. So the content cannot simply be copied across. Every document has to arrive with its identity, its dates, its attachments and its editorial state intact, which makes a replatform a records problem long before it is a website problem.

Migration architecture and platform engineering inside a government programme

A partner agency led the programme and brought us in as their engineering partner for the move onto a government-managed Drupal(Opens in a new tab/window) platform. We worked across both properties, the regulator's main site and a second site for one of the schemes it administers, and provided:

  • migration architecture
  • platform development
  • front-end engineering

Government delivery is rarely a single team. Several suppliers and the regulator's own developer all worked in the same codebase alongside the design and content teams, and keeping that shared build coherent was part of our work.

2 systems, a single set of documents, reconciled across 3 identifiers

The documents the site publishes did not live in the old website. They live in the regulator's enterprise records management system, held as formal records with their own numbers and revisions.

That left 2 sources describing the same material, each holding half the answer. The legacy site knew which document belonged to which review, in what order and on what date. The records system held the authoritative file.

The same document could also be known by 3 different identifiers, depending on which system you asked. So we built the reconciliation. A single lookup resolves a document across all 3 and settles which wins.

Anything the records system has not yet sent gets a placeholder, so a review can be assembled now and completed on the next sync.

A migration you can run more than once, without republishing what was withdrawn

A migration this size is never a single run. You run it, review what landed, correct something, run it again, and that only works if the second run recognises what the first one created.

Legacy pages were known by their web addresses, so we derived each item's identifier from its own path: same path, same identifier, every run. Reviews that reference other reviews are built in a second pass. For a client, that is the difference between a migration you can rehearse and one you get a single attempt at.

The decision we would lead with, though, is smaller and matters more. If an editor had unpublished a page, re-running the migration left it unpublished. On a regulator's site that is not a nicety: a withdrawn determination that quietly reappears is a regulatory problem, not a content bug.

And we proved the result rather than asserting it, comparing the source data against what actually landed in Drupal.

Where the regulator's publishing rules live: review types encoded in the site

Which documents appear under which tab of a review depends on the kind of review it is, and those rules belong to the regulator, so we encoded them in the site itself. An editor publishes a document once, sees only the fields that apply to that review type, and it lands where the rules say it should.

The public gets a timeline that opens at today, and every review page offers an accessible copy of a document on request. For a client, that means the publishing rules live in the platform rather than in a style guide someone has to remember.

What it added up to: a migration delivered in releases, not a single cutover

The work began in 2020 and the build ran across 2021, released more than 70 times inside that single year. That is a release rhythm rather than a big-bang cutover, which is what most government teams are quietly hoping for. The legacy address structure was kept wholesale, including the front page, so published citations pointed at addresses that still existed after the move.

More than 70 releases inside a single year, then 2 years of upgrades by the next team.

Then we handed it over, and it kept going: the team that received the platform carried on releasing and upgrading it through the next 2 years of Drupal work. For a migration, that is the outcome worth measuring. Not only that it landed, but that the next team could keep it moving.

For migrations where the content carries legal weight

Everything on this page is 4 of our services on one government replatform: migration architecture, platform development, front-end engineering, and the deployment work that put both sites on a government-managed platform.

If you run a regulator, a department, or any public body whose website is where decisions are formally published, this is the shape the engagement takes: the records reconciliation settled before the content moves, a migration that can be re-run without republishing anything withdrawn, and the legacy addresses kept so published citations still have somewhere to land. The same engineering is available with AI-assisted delivery where it suits the work, at the same tested standard.

If you are replatforming a site whose documents are cited elsewhere, and nobody can yet tell you what happens to those citations, send us the address structure you have to keep.

Independent Pricing and Regulatory Tribunal website replatform

When the website is the public record: a regulator's statutory publication channel

The Independent Pricing and Regulatory Tribunal(Opens in a new tab/window) is the New South Wales independent economic regulator. Its statutory work includes:

  • setting the maximum prices for water, public transport and council rates
  • licensing private water utilities
  • running formal public reviews with consultation periods, submissions and hearings

Its website is not a brochure. It is the regulator's statutory publication channel, and a determination is published at the moment it appears there.

Councils, utilities and the lawyers who advise them cite that site, and those citations are expected to keep resolving for years. So the content cannot simply be copied across.

Every document has to arrive with its identity, its dates, its attachments and its editorial state intact, which makes a replatform a records problem long before it is a website problem.

Our part in the programme: migration architecture on GovCMS

Salsa Digital(Opens in a new tab/window) led the programme and brought us in as their engineering partner for the move onto GovCMS(Opens in a new tab/window), the Australian government's shared Drupal(Opens in a new tab/window) platform.

We worked across both properties, the regulator's main site and the second site for the energy savings scheme it administers. Our part covered:

  • migration architecture
  • platform development
  • front-end engineering

Government delivery is rarely a single team. Several suppliers, the regulator's own developer and the platform operator all worked in the same codebase alongside the design and content teams, and keeping that shared build coherent was part of our work.

2 systems, a single set of documents: reconciling the records

The documents the site publishes did not live in the old website. They live in the regulator's enterprise records management system, held as formal records with their own numbers and revisions.

That left 2 sources describing the same material, each holding half the answer. The legacy site knew which document belonged to which review, in what order and on what date. The records system held the authoritative file.

The same document could also be known by 3 different identifiers, depending on which system you asked. So we built the reconciliation.

A single lookup resolves a document across all 3 and settles which wins, and anything the records system has not yet sent gets a placeholder, so a review can be assembled now and completed on the next sync.

A migration you can run more than once, without republishing withdrawn content

A migration this size is never a single run. You run it, review what landed, correct something, run it again, and that only works if the second run recognises what the first one created.

Legacy pages were known by their web addresses, so we derived each item's identifier from its own path: same path, same identifier, every run. Reviews that reference other reviews are built in a second pass. For a client, that is the difference between a migration you can correct and one you have to redo.

The decision we would lead with, though, is smaller and matters more. If an editor had unpublished a page, re-running the migration left it unpublished.

On a regulator's site that is not a nicety: a withdrawn determination that quietly reappears is a regulatory problem, not a content bug. And we proved the result rather than asserting it, comparing the source data against what actually landed in Drupal.

Where the regulator's publishing rules live: encoded in the site

Which documents appear under which tab of a review depends on the kind of review it is, and those rules belong to the regulator, so we encoded them in the site itself.

An editor publishes a document once, sees only the fields that apply to that review type, and it lands where the rules say it should. For a client, that means the complexity sits in the platform rather than in an editor's training.

The public gets a timeline that opens at today, and review pages offer an accessible copy of a document on request.

What it added up to: 73 releases, then 2 years of upgrades

The work began in 2020 and the build ran across 2021, released 73 times inside that single year. That is a release rhythm rather than a big-bang cutover, which is what most government teams are quietly hoping for.

The legacy address structure was kept wholesale, including the front page, so the addresses behind inbound links and published citations were preserved rather than replaced.

Then we handed it over, and it kept going: the team that received the platform carried on releasing and upgrading it through the next 2 years of Drupal work.

73 releases inside a single year, then 2 more years of upgrades by the team that received it.

For a migration, that is the outcome worth measuring. Not only that it landed, but that the next team could keep it moving.

For migrations where the content carries the risk

Everything on this page is 3 of our services on one government replatform: migration architecture across 2 sources of truth, platform development on a shared government Drupal platform, and front-end engineering that put the regulator's own publishing rules into the site.

If you run a regulator, a department or any site whose content is the public record, this is the shape the engagement takes: a migration you can re-run and correct, editorial decisions preserved across re-runs, and legacy addresses carried across rather than dropped. The same engineering is available with AI-assisted delivery where it suits the work, at the same tested standard.

If your next replatform has to carry documents that live in a records system rather than in the website, tell us where your documents actually live.

Three federal websites, built where custom code is not allowed

When the platform will not let you write code: the GovCMS SaaS constraint

If you publish on a government platform, you have probably met the trade it makes. GovCMS, the Australian Government's whole-of-government Drupal(Opens in a new tab/window) service, gives agencies accreditation, compliance and managed hosting. In return, its software-as-a-service tier permits no custom code:

  • no bespoke modules
  • no server-side services
  • nothing outside the vetted distribution

It is easy to read that as a wall. Almost every hard requirement a team has met before was answered by writing code, and here that answer is gone.

Our part in the work: architecture, build and migration engineering

A federal government department was moving its public web presence onto GovCMS, and its public channels carry the whole of what it does. A partner agency delivering that move brought us in as its engineering partner, with design carried by a separate studio.

We provided technical leadership, platform engineering and migration engineering:

  • the scaffolding
  • the content models
  • the themes
  • the deployment tooling
  • the migration codebase itself

3 sites on one platform: a main channel, an intake site and a publication site

The engagement covered 3 sites on the same platform:

  • the department's principal public channel, carrying reference information, publications, profiles, news, events and the programmes it funds
  • a standalone public front door that takes structured reports from the public through a single intake form, live in 8 weeks
  • a compact standalone publication site, shipped in 5 weeks alongside it

The main site's content model is built around the department's own subject matter, with its primary reference entities as first-class content rather than tags, so anything published can be placed against them.

Business logic that had to live in configuration: layout modifiers and design tokens

The most transferable piece is layout. Editors wanted per-section control over background images, gradients, colours, padding and height, at chosen breakpoints, so we modelled presentation as content.

Any component can carry any number of modifiers, each a small piece of content with its own media query, rendered as styling scoped to that component. An editor can combine a background image, extra top padding above tablet width and a minimum viewport height, without a developer and without code the platform would have refused. For a client, that reads as independence: your editors restyle a section themselves, and nobody has to ask first whether the platform will allow the code.

We took the same approach to the whole-of-government design system, re-theming it by assigning the department's design tokens into the system's own variables rather than overriding its output. Override the output and every release becomes a merge conflict. Assign tokens and it becomes a version bump.

We also restored the heading structure that paragraph-composed pages quietly lose, which screen readers rely on.

Moving 20 years of public content with no database to read

Roughly 20 years of published material had to move with the site: reference pages, publications, profiles, news releases and the document library behind them. There was no database to read and no API to call, so the source of record became the live public site, harvested and normalised into structured data.

That creates the problem any GovCMS team with a migration ahead of them is about to meet. A migration of this shape cannot be written without custom code, and the destination does not accept custom code. We resolved it architecturally: the migration ran as its own project on the platform-as-a-service tier, where custom code is permitted, and the content landed in the software-as-a-service site.

Archived material was treated as its own class throughout, because 20-year-old content does not have the shape of this morning's media release. And validation was written as configuration, committed beside the migration, so what landed could be checked against what was harvested.

Most migrations assert that they are correct. This one could be asked. For a client, that is the difference between being told a migration landed correctly and being able to check that it did.

What it adds up to: 10 months to build, 3 years of onward maintenance

The main site was built in about 10 months and went into service with 20 years of content behind it.

The measure we like most came later: it was still being maintained and upgraded 3 years after we handed it over, including a platform update and work toward a newer Drupal version, carried by the team that received it.

Built in 10 months, and still being maintained and upgraded 3 years after we handed it over.

A site still being improved by people who did not build it is solid evidence that it was built to be handed on.

For agencies that cannot ship custom code

Everything on this page is 5 of our services running inside one whole-of-government platform: architecture that puts the logic where the platform allows it, development of the content models and themes, the deployment tooling that ships them, migration engineering that could be checked against its source, and accessibility carried through the build.

If you publish on GovCMS software-as-a-service, or you are weighing a move onto it, this is the shape the engagement takes: requirements answered in configuration and theme rather than in modules you are not allowed to ship, a design system consumed by token assignment so an upgrade stays a version bump, and a migration that runs where custom code is permitted and lands where it is not. The same engineering is available with AI-assisted delivery where the work suits it, most obviously across migration mapping and validation.

If you have a requirement your GovCMS site will not let you build, tell us what it is and we will tell you where it can live.

Department of Foreign Affairs and Trade websites on GovCMS

GovCMS: when the platform will not let you write code

If you publish on a government platform, you have probably met the trade it makes. GovCMS(Opens in a new tab/window), the Australian Government's whole-of-government Drupal(Opens in a new tab/window) service, gives agencies accreditation, compliance and managed hosting.

In return, its software-as-a-service tier permits no custom code: no bespoke modules, no server-side services, nothing outside the vetted distribution.

It is easy to read that as a wall. Almost every hard requirement a team has met before was answered by writing code, and here that answer is gone.

Our part in the work: technical leadership and migration engineering with Salsa Digital

The Department of Foreign Affairs and Trade runs Australia's international relations, trade policy, development assistance and consular services, and its public web presence carries all of it. Salsa Digital(Opens in a new tab/window), delivering the move onto GovCMS, brought us in as its engineering partner, with design carried by a separate studio.

We provided technical leadership, platform engineering and migration engineering:

  • the project scaffolding and the deployment tooling
  • the content models behind all 3 sites
  • the themes, including the design-system work
  • the migration codebase itself

3 GovCMS sites for a department with a global remit

The department's public presence was built as 3 sites.

  • the corporate site, its main public channel, carrying country and regional information, publications, profiles, news, events and the programmes it funds
  • tradebarriers.gov.au, the national front door where Australian exporters report the obstacles they meet in overseas markets that are not tariffs: quarantine rules, labelling requirements, customs delays. It takes reports through a single structured intake form, and was live in 8 weeks
  • a site for the Cairns Group, the coalition of agricultural exporting nations chaired by Australia, shipped in 5 weeks

The corporate site's content model is shaped like a foreign ministry, with country pages as first-class content rather than tags, so anything published can be placed geographically.

Business logic that had to live in configuration: layout modifiers and design tokens

The most transferable piece is layout. Editors wanted per-section control over background images, gradients, colours, padding and height, at chosen breakpoints, so we modelled presentation as content.

Any component can carry any number of modifiers, each a small piece of content with its own media query, rendered as styling scoped to that component. An editor can combine a background image, extra top padding above tablet width and a minimum viewport height, without a developer and without code the platform would have refused. For a client, that reads as independence: your editors change how a page looks without booking developer time.

We took the same approach to the Australian Government Design System, re-theming it by assigning the department's design tokens into the system's own variables rather than overriding its output. Override the output and every release becomes a merge conflict. Assign tokens and it becomes a version bump.

We also restored the heading structure that paragraph-composed pages quietly lose, which screen readers rely on.

Moving 20 years of public content: a migration built where custom code is allowed

Roughly 20 years of published material had to move with the site: country pages, publications, profiles, news releases and the document library behind them. There was no database to read and no API to call, so the source of record became the live public site, harvested and normalised into structured data.

That creates the problem any GovCMS team with a migration ahead of them is about to meet. A migration of this shape cannot be written without custom code, and the destination does not accept custom code.

We resolved it architecturally: the migration ran as its own project on the platform-as-a-service tier, where custom code is permitted, and the content landed in the software-as-a-service site.

Archived material was treated as its own class throughout, because 20-year-old content does not have the shape of this morning's media release.

Validation was written as configuration, committed beside the migration, so what landed could be checked against what was harvested. Most migrations assert that they are correct. This one could be asked.

For a client, that is the difference between trusting a migration and being able to check it.

What it adds up to: 10 months to build, still maintained 3 years on

The main site was built in about 10 months and went into service with 20 years of content behind it.

The measure we like most came later: it was still being maintained and upgraded 3 years after we handed it over, including a platform update and work toward a newer Drupal version, carried by the team that received it.

Built in about 10 months with 20 years of content behind it, and still being upgraded 3 years after handover.

A site still being improved by people who did not build it is strong evidence that it was built to be handed on.

For teams publishing inside a platform they cannot extend

Everything on this page is 5 of our services running inside a platform that permits no custom code: architecture that puts business logic in configuration, development within a vetted distribution, migration at 20-year scale, DevOps and hosting through the platform's own tooling, and accessibility work carried in the theme.

If you publish on GovCMS, or on any accredited government platform that fixes what you are allowed to build, this is the shape the engagement takes: presentation modelled as content so editors keep control, design-system work done by assigning tokens rather than overriding output, and a migration that can be checked rather than trusted. The same engineering is available with AI-assisted delivery where it suits the work.

If your GovCMS build has a requirement the software-as-a-service tier will not let you code your way out of, tell us what the platform is blocking.

Contributing to Queensland's open data platform

Publishing the data is the easy half: what an open data portal needs after the files

If your organisation publishes data for the public to reuse, hosting the files is rarely what makes it hard. A spreadsheet on a server is a solved problem. The interesting questions all start after publication.

The same 3 questions come up on every portal.

  • Someone needs a dataset you have not released yet. How do they ask, and how does anyone else see that the request was made?
  • Someone spots an error in a column, or cannot work out how a figure was calculated. Where does that go, and does it end up attached to the data or lost in a generic contact form?
  • A developer weighing up whether to build on your data has to judge, before investing any time, whether it is well maintained and licensed for their purpose.

Each of those is a real product problem, and none of them is solved by publishing more files.

Queensland's open data portal: CKAN and the extensions a government adds to it

The Queensland Government's open data portal, at data.qld.gov.au, publishes state datasets for public reuse. It is the practical expression of open data policy: anyone can find, download and reuse what a government agency holds, under a licence that permits it. Its readers are the public, journalists, researchers and businesses building products on public data, alongside the agency staff publishing it.

It runs on CKAN, the open-source data portal platform behind many national and state open data sites around the world. CKAN handles the catalogue itself. Everything a particular government needs on top of that is an extension, and Queensland maintains its extensions as public repositories anyone can read.

Alongside the portal sits the Queensland business services catalogue, the directory of services government offers to businesses. That one is Drupal(Opens in a new tab/window).

Our contribution, in the open: public CKAN repositories and a Drupal catalogue build

Between 2019 and 2021, engaged through Salsa Digital(Opens in a new tab/window), we contributed to the CKAN extensions behind the portal:

  • the Queensland-specific behaviour that shapes the portal itself
  • its theme
  • the extensions that answer those 3 questions directly

Our changes sit alongside those of a much wider group of contributors, in repositories the Queensland Government owns and publishes itself.

That is a different working posture from a private client repository. Changes are visible, attributable and reviewed in public, by a community that did not hire you and has no particular reason to be polite about it. For a client, that posture reads as verifiable work: you can read the changes we made without taking our word for any of it.

Contributing successfully in that setting, in Python and CKAN rather than the PHP and Drupal we work in most days, is a credential in its own right.

On the business services catalogue we carried more of the load. We were the leading contributor to its Drupal build.

The 3 problems open data publishers keep hitting: requests, comments and certification

The extensions we worked on are worth understanding even if you never run CKAN: they are well-considered answers to the 3 questions above.

  • Data requests turn a portal from one-way publishing into a demand signal. The public asks for datasets that have not been released, in the open, so agencies can see what people actually want rather than guessing at it.
  • Dataset comments give quality feedback a home. A threaded discussion attached to the data itself means an error report or a methodology question lands where the next reader will see it.
  • Third-party certification is the trust signal. Open Data Institute certificates rate a dataset's quality, licensing and sustainability against a published standard, so a developer can judge it without having to ask anyone.

Most organisations that publish data publicly run into the same 3 problems: a council, a regulator, a research body, a university. CKAN's answers to them are a useful reference even when the build in front of you is Drupal. For a client, that reads as time saved: the hard questions are already named, so a portal project starts at your own data rather than at first principles.

What the work left us with: maintained extensions and a second platform ecosystem

The portal is live, and the extensions are public, active and still maintained by the Queensland Government. For work of this shape that is the outcome that matters: the code stayed in service and other people kept building on it.

The extensions we contributed to between 2019 and 2021 are still public, active and maintained by the government that owns them.

For us it settled a question clients ask often. CKAN is Python, with its own community, its own extension model and its own deployment shape. Merged contributions in it answer "can you work outside Drupal?" concretely rather than with an assurance.

It also left us with a working understanding of open data as a domain. Those 3 problems are the first things we raise when a client tells us they are about to start publishing.

For organisations opening their data to the public

Everything on this page is one of our services in an unfamiliar setting: development, carried out in public repositories a state government owns, in Python and CKAN alongside the Drupal we work in most days.

If you run a council, a regulator, a research body or a university about to publish data for the public to reuse, this is the shape the engagement takes: the 3 questions answered before the build starts, work done in whatever ecosystem your portal already runs on, and changes anyone can read. The same engineering is available with AI-assisted delivery where it suits the work, at the same tested standard.

If you are standing up an open data portal, or running one where the datasets go out and nothing comes back, tell us what you publish and who needs it.

University of Melbourne teacher candidate assessment platform

Multi-tenancy in practice: a single assessment, many institutions

Some software has to be the same everywhere and different everywhere at once. An assessment used in selecting candidates into teaching degrees is exactly that.

The instrument has to hold its shape wherever it runs, while each institution wants its own:

  • branding
  • cohort
  • admission dates
  • rules about how a candidate gets an account

Build it once and run an instance per institution per cycle: that is the obvious answer, and it is also where the work is. Every new instance starts life as a copy of a working one. A copy is only ever as safe as your ability to prove it still works.

Our part in the partnership: development, testing and maintenance from 2018

The Teacher Capability Assessment Tool is owned by the University of Melbourne and was built by Salsa Digital(Opens in a new tab/window), whose team carried the platform and its relationships with the institutions using it. We joined the engineering in 2018.

Our work ran across the running instances:

  • software development on the application
  • automated testing across the institution instances
  • ongoing maintenance

A point worth saying plainly. The assessment instrument belongs to the institutions that use it; our work was the software it runs on.

A single PHP codebase, an instance per institution and per cycle

Candidates registered, confirmed who they were, and worked through a set of structured modules at their own pace. Staff worked over the cohort through an administrative dashboard, and results left the system as PDF reports. Each institution and each intake had its own instance, all running from the same codebase.

None of this was Drupal(Opens in a new tab/window). It is a classic PHP application on Zend Framework 1:

  • jQuery and Bootstrap on the front end
  • a grid component for the administrative tables
  • a PDF library for the reports

Most of our work is Drupal, but the engineering underneath any long-lived platform is the same: a real domain model, a test suite that means something, and a repeatable path to production.

Making a copy safe to ship: end-to-end Behat testing per instance

The testing is the most interesting engineering on the project, because it takes the multi-tenancy problem head on. Every institution instance had its own end-to-end profile with its own base URL and matching tag filter, and a single script ran them all together.

2 details are worth borrowing. Registration issued a temporary password by email, so an end-to-end test could not get through the front door without reading it. The suite ran against a real mail catcher and took the password out of the message, exactly the way a candidate would.

Some institutions provisioned their candidates directly rather than letting them register themselves. Rather than skip those instances or test a path they had deliberately closed, we re-used a real account and reset its progress between runs, behind a single flag.

When something did break, the suite saved a screenshot at that moment, through our open-source Behat screenshot extension(Opens in a new tab/window), so a failing run explained itself instead of just going red.

All of it served a single purpose: every new instance was a copy of a working one, and the end-to-end suite is what made copying safe. For a client, that reads as confidence: each admission cycle starts from an instance the suite has already checked.

Atomic releases onto the university's own infrastructure

The platform ran on the University of Melbourne's own infrastructure, so releases followed the university's process rather than ours. That made the release path a documented, hand-run sequence:

  • build the artefact
  • send it up to the server
  • unpack it beside the running application
  • swap the directories in a single move, leaving the previous release exactly where it stood

That last part is the whole trick. The cutover is a single move rather than a file-by-file copy, and the rollback is the same move in reverse. When a client's platform team owns the servers, a release procedure that fits their process and stays safe beats one that fits ours.

What it adds up to: multiple institutions, multiple cycles

The platform ran for multiple institutions across multiple admission cycles. Instances ran for other universities, for state education departments and for Catholic education authorities, each with its own cohort and intake dates.

A single codebase, several unrelated organisations, and a fresh instance for every admission cycle.

That is the outcome worth naming. Several unrelated organisations ran the same software on their own terms, and each year's instance could be stood up with confidence rather than crossed fingers. For a client, that is what a well-drawn platform buys: the next institution is a setup exercise, not a new build.

For platforms that several organisations have to run

Everything on this page is 2 of our services running on one long-lived platform: software development on an application several organisations depend on, and support and maintenance across every running instance.

If you run an assessment or admissions platform that several institutions share, or a custom application that has outlived the team who built it, this is the shape the engagement takes: an end-to-end suite that checks each instance before it ships, a release path that fits your own platform team's process, and engineers who work on the stack you already have. The same engineering is available with AI-assisted delivery where it suits the work, at the same tested standard.

If your next admission cycle depends on standing up another instance of a platform nobody has tested in a while, tell us what it runs on.

Contributing to GovCMS, the Australian Government's shared Drupal platform

The GovCMS foundation dozens of government websites stand on

GovCMS(Opens in a new tab/window) is the Australian Government's shared Drupal(Opens in a new tab/window) platform, run by the Department of Finance. Agencies across federal, state and local government build their websites on it and get security, compliance and managed hosting in return for working inside the platform's rules. It is common ground under a large part of the Australian government web estate.

Working on a platform like that is a different kind of work from building one agency's website. A decision you make on an agency site shapes that site.

A decision you embed in the platform's own tooling shapes every project started from it afterwards, for years. That is where we spent 2018 to 2020.

What a project scaffold actually decides

Every new site on a shared platform starts from a scaffold: a project template that arrives with the platform's opinions already made.

  • how the project is laid out and how its dependencies are managed
  • how a developer runs it on their own machine
  • what the automated checks look at before a change is allowed through
  • what the platform will simply refuse to deploy

Most people never see this layer, which is exactly why it matters. Get it right and every team starting a project inherits a safe, tested path to production without having to think about it. Get it wrong and every team inherits the same friction, one project at a time.

What we contributed to the GovCMS scaffolds

We were the leading contributor to 2 of the platform's project scaffolds, govcms7-scaffold and saas-scaffold, and to the continuous integration that runs alongside them. We also contributed to:

  • the platform's hosting integration on Lagoon
  • its shared CI tooling and provisioning automation
  • its Drupal 8 distribution and the platform's own website
  • 2 of its content-safety modules

It is worth being precise about what that means. This is contribution, not stewardship. The platform belongs to the Department of Finance and its direction always has.

What the public record shows is that across roughly 3 years we were the leading contributor to the templates every consuming project starts from. The repositories are open source, so anyone can check that for themselves, which is the whole reason it is worth saying.

Scaffold design: opinionated and generic at the same time

A platform scaffold has to pull in two directions at once. It has to be opinionated enough to be genuinely useful, so that a team gets a working, tested project on day one. And it has to be generic enough to serve every agency on the platform, from a small statutory body to a large department.

Then there is the boundary. Some files belong to the project and some belong to the platform, and a project that edits the wrong one cannot deploy at all. That is why these scaffolds carry an explicit list of files a project must leave alone.

Drawing that line, between what a team may change and what the platform owns, is the central design problem of this kind of work. It is the difference between a template teams trust and one they quietly fight.

The same problem, solved twice: GovCMS and Vortex

In the same period we were answering the identical question in our own practice. Our open-source Drupal project template, Vortex(Opens in a new tab/window), grew out of it: how do you give every project a build, test and deploy path that is standard enough to maintain and flexible enough to be worth using?

Doing both at once meant each one informed the other. It is also a fair answer to a question we are asked often, which is why anyone should trust our project template. Because we did the same job inside a federal government platform, in public, where the result can be read.

What it added up to: platform foundations we later built on

The scaffolds shipped and were used. Government agency websites were built from them, including several we went on to deliver ourselves.

Across roughly 3 years, the leading contributor to the project templates every GovCMS site starts from, in repositories anyone can read.

Contributing to a platform's foundations and then delivering agency sites on top of those foundations is an unusual combination. For an agency choosing a partner on the platform, the practical difference is a team that knows which files the platform owns before the first deploy fails.

None of it is locked away, either. The platform's tooling is open source, so the work is there to read.

For agencies building on GovCMS

The work on this page sits behind 3 of our services: platform architecture, Drupal development, and the DevOps and hosting engineering that decides how sites reach production.

If you run an agency site on GovCMS, or you are choosing between SaaS and PaaS for your next build, this is the practical advantage: we contributed to the templates your project will start from, so the platform's rules are not a surprise to us. The same engineering is available with AI-assisted delivery where it suits the work, at the same tested standard.

If a GovCMS build or migration is on your roadmap, tell us where it stands.

Vortex, the Drupal project template

The 2 costs nobody puts on the budget: setup and drift

Ask a team that runs more than 1 Drupal(Opens in a new tab/window) site where its time goes, and 2 answers come back.

The first is setup. Every new project spends weeks on the same groundwork before anyone builds a feature:

  • local environments
  • CI pipelines
  • hosting wiring
  • code quality tooling
  • a test harness

The second is drift. Once a project is running it grows its own arrangement of tooling, so a year later moving a developer between 2 of your own sites means learning 2 different machines.

Neither cost appears on a budget line, and both are paid again on every project.

Installed once and kept current: local environment, CI pipelines and hosting

Vortex(Opens in a new tab/window) is a Drupal project template: a tested foundation you install once, pick features from, and then keep current for the life of the project.

The template is the pre-configured Drupal project itself, wired together and working on day 1:

  • a containerised local environment
  • CI pipelines
  • hosting integrations
  • code quality tooling
  • a testing harness

Documentation ships with it, including an onboarding checklist for new team members. An installer adds only the features you chose, from hosting and CI provider through to theme and AI agent instructions. On the current line that tool is the installer; the next major moves the job into a dedicated Vortex CLI.

That upgrade path is what separates Vortex from a starter kit, which is a one-time copy frozen at whatever it got right in its year. Vortex keeps the path open, so a project set up in its first year can adopt improvements made in its third through the same tool that created it.

For a client, that reads as continuity: the foundation under your site keeps getting the improvements made after your project started.

Whichever features you pick, local, CI and hosting all run the same provisioning path. That single decision is where "works on my machine" stops being a recurring argument.

The quality gates arrive switched on: secret scanning, static analysis, 90 per cent coverage

Plenty of templates leave quality tooling as an exercise for the reader. Vortex ships the gates configured and running across the whole codebase:

  • secret scanning
  • dependency auditing
  • container linting
  • static analysis
  • coding standards

A 90 per cent code coverage threshold fails the build by default, with the result posted back onto the pull request. Visual regression waits behind an opt-in label, so an expensive check runs only on the changes that warrant it. Third-party CI actions are pinned by commit hash, a ready answer to a supply-chain question many teams are now being asked.

Every gate can be switched off with a single variable, and that matters more than it sounds. A team can adopt the pipeline on day 1 without being blocked by it, then tighten it as they go. It is the difference between a pipeline people keep and one they quietly delete.

The documentation is held to the same standard: linted, tested, and gated against drifting out of step with the code.

9 years in and busier than ever: 111 releases across Drupal 7 to 11

The usual failure mode of a project template is quiet abandonment: excellent for 18 months, then attention moves elsewhere and the repository goes still.

Vortex began in July 2017 and has shipped 111 releases since. It has tracked Drupal 7, 8, 9, 10 and 11 across their lives, and today it targets Drupal 11.

Releases go out on a stated monthly cadence, borne out across the recent run. A second major version is already published alongside the first, with the release plumbing built so that promoting a new major to the default is a single configuration change.

It is being developed more actively today than in any year of its life.

111 releases since 2017, across Drupal 7 to Drupal 11, and busier today than in any year of its life.

For a client, that history reads as low risk: the foundation under your project is maintained by the team you are already working with.

Open source under GPL-3.0, and used on the work we are paid for

Vortex is open source under GPL-3.0 and developed in public: repository, issue tracker, releases and documentation are all open. Community support runs through Drupal Slack and GitHub issues, and paid support is available for teams that want a commercial contact behind it.

We use it ourselves, which is the part that keeps it honest. Our own website runs on Vortex and is offered openly as a reference for what a long-lived Vortex project looks like, and the client platforms we support run on it too. The template meets real delivery pressure, not only its own test suite.

The flow runs both ways. Tools that began inside client work ship with Vortex, including our Behat step library(Opens in a new tab/window), CI runner image(Opens in a new tab/window) and artifact deployer(Opens in a new tab/window). Pieces that outgrow it are published in their own right.

For teams paying the setup cost on every Drupal project

Everything on this page is 4 of our services pointed at our own product: the architecture of the template, its development, the DevOps and hosting wiring it ships with, and the support and maintenance that has kept it current since 2017. The same template ships the AI agent instructions behind our AI-assisted delivery, and the gates decide what is allowed to merge.

If you run a portfolio of Drupal sites, or a team that starts a new project every few months, this is the shape the engagement takes: your sites build, test and deploy the same way, new developers onboard against a stack they have seen before, and improvements arrive through the same tool that set the project up.

If your Drupal projects have each grown their own build and nobody can move between them, tell us what your setup looks like today.

Victorian Government Single Digital Presence platform

Government is organised by department. People are not: the case for one shared web platform

When you need something from government, you rarely know which department owns it. You know what you need: a permit, a payment, advice after a storm.

Yet a lot of government websites are still laid out the way the organisation is, because that is how digital tends to grow. One department at a time, each with its own site, its own supplier and its own way of publishing.

Victoria set out to change that. The Single Digital Presence programme aimed to bring 50 government websites onto one platform with one publishing standard, working to a principle that is still the clearest sentence we know on the subject: content belongs to the people who need it, not to the department that happens to own it.

What we built: the API layer, the multi-site engine and the testing architecture

Single Digital Presence is open source, and the record of who built what is public with it. Starting in 2017, we created most of the repositories behind the platform's Drupal(Opens in a new tab/window) layer, including its API layer, its multi-site engine and its testing architecture.

The pattern was the same across all of them. We laid the foundations before any feature work:

  • the project scaffolding every repository is built from
  • the continuous integration that runs on each change
  • the automated tests over the behaviour that matters
  • the developer workflow the teams work in day to day

The department's own team and its delivery partners then filled that structure with features. For a client, that order reads as a head start: whoever arrives next inherits a working pipeline instead of building one. The programme's technical lead credited the distribution and its testing approach from a conference stage in 2019.

In 2019 the Department of Premier and Cabinet contracted us directly, off the Victorian Government eServices Register, to write the developer documentation for the platform: how to work with the code, test an API endpoint and release a module. It shipped as a documentation site with a build that refuses to deploy if an internal link is broken.

One Drupal content system, many public websites: decoupled publishing with real preview

The heart of the platform is one Drupal content system serving many separate public websites, each with its own domain, brand, menus and homepage, all edited by agency staff in the same place. There is no separate installation per site.

A site is a piece of structured content, which makes bringing another agency on board a content decision, not a rebuild. For an agency joining later, that reads as a shorter path to launch: your site is configured on a platform that already runs, rather than procured and built again.

The public websites are rendered by a JavaScript front end, so Drupal serves content rather than pages. That split is good for performance and reuse, and it raises the question every organisation asks about decoupled publishing: how do editors preview their work when the content system renders nothing?

The platform's answer is one of the neatest we have seen, and it was not ours. The editor clicks Preview and lands on the real front end, which renders the unpublished draft exactly as the public will see it. We have carried that technique with us ever since.

Keeping a platform honest as it grows: shared testing across many repositories

The platform's Drupal code lives in many small repositories, each tested on its own. That is good for release safety and hard on consistency: every repository needs its own development environment, test harness and build pipeline, and copies of the same setup drift apart the moment nobody is watching.

We answered it in 2 pieces. The first was a shared test module giving every repository a neutral content type to write tests against, with a filter that scrubs its own fingerprints out of the site's exported configuration, so the test harness stays out of what the site ships. The second was a development toolkit that repositories fetch rather than copy: one small file each, one command surface, one place to change how everything is built and tested.

Where it got to: vic.gov.au, nearly a decade on

The platform is in service. vic.gov.au(Opens in a new tab/window) runs on it, its repositories are public and still active, and its front-end component library is published for anyone to install.

Each layer, hosting, content management and front end, was designed to be taken on its own, so another agency could adopt just the part it needed. Other Victorian agencies were building on the model within the first 2 years.

Nearly a decade after those first commits, vic.gov.au still runs on the platform.

The work outlived the engagement, and the teams who came after us could keep building on it. That is the outcome we care about most.

For governments bringing many websites onto one platform

Everything on this page is 3 of our services on one shared government platform: architecture for a multi-site Drupal system, development of the modules and the API layer behind it, and the DevOps that builds and tests every repository.

If you run a department, an agency, or a group of sites that each grew their own way, this is the shape the engagement takes: foundations first, tests and pipelines before features, and a platform layer other teams can build on. The same engineering is available with AI-assisted delivery where it suits the work, at the same tested standard.

If you are consolidating agency websites onto one publishing platform, or trying to keep a growing set of repositories consistent, tell us what your estate looks like.

Victoria University web platform

A university web platform is never finished: upgrades, new brands and content migrations

A university website carries a decade of accumulated content, an audience that never accepts an outage as an explanation, and a platform that reaches end of life on a schedule somebody else set. There is always a version to upgrade, a brand to stand up, content to bring home.

Most of that work arrives irregularly and none of it can be deferred, which is an awkward shape to hire for. Victoria University(Opens in a new tab/window) runs its own Web Services team in Melbourne and brings in specialists for the peaks. We have been one of them since 2017.

Working alongside the university's own team: platform engineering from Drupal 7 to Drupal 11

The university's team owns the estate day to day. We provide the platform engineering, the architecture and the delivery practice underneath it, and we hand over what we build as we go. Building technical understanding inside their team has been part of the arrangement from the first year, not something bolted on at the end.

In practice that means:

For a client, that reads as capacity without a handover cliff: the specialists arrive for the peak, and what they built stays understood inside your own team.

New brands, and content brought home: a vocational site and an institute migration

The university's vocational brand had been sitting inside the main site as a section of it. We built it out as its own website on its own domain, with the university's own team moving the content across.

A few years later we consolidated the separate site of one of the university's policy institutes into the main site. A research institute's whole value is its published papers and the authors attached to them.

So instead of writing scripts for 2 months and finding out on launch night whether they covered everything, we ran the migration continuously throughout the build, proving it against the real content every day. For a client, that turns launch night into a rehearsal you have already run rather than the first full test.

Researcher profiles people can actually find: a searchable directory of academics

An academic profile is commercial infrastructure for a university rather than a vanity page. It is how:

  • an industry partner finds a collaborator
  • a research student picks a supervisor
  • a journalist finds someone to comment

Working to the university's own requirements, our team built its public directory of academics: a profile the academics drive themselves through an editorial workflow, and a search that finds people by expertise rather than by name. Publications, grants and supervision history arrive from the university's own systems, and the rest belongs to the academic to write.

For anything opt-in, adoption is the number that matters. Within weeks of launch, 271 of the 354 academics in scope had a published profile.

Moving the whole platform with no planned downtime: the Lagoon hosting migration

In 2021 both public websites moved onto one hosting platform, amazee.io Lagoon, and every non-production and preview environment moved with them. That second part is the difference between relocating a website and moving a team's whole way of working.

There was no planned downtime, and that came from sequencing rather than heroics. Each site was stood up on the new platform first, its integrations moved and tested there, and the university's team validated it with their own tooling and acceptance testing before traffic followed. Publishing paused for a business day.

What 9 years adds up to: 3 measured results and 2 open-source tools

3 pieces of this work have a number on both sides of them.

  • Long-lived sites accumulate weight, and the weight is usually not growth. Most of what was sitting in this one's database turned out to be historical data nothing referenced any more, and removing it left the database 63 per cent smaller.
  • Editors on large sites often wait hours for a published change to appear. We measured that end to end and brought the worst case down from most of a day to about 20 minutes.
  • Asked to speed up a test suite that took close to 30 minutes, we found 3 of our 4 assumptions about the cause were wrong: the tests were waiting on third-party assets, not on the application. That path ended up about 3 times faster.
A database 63 per cent smaller, and a published change live in about 20 minutes instead of most of a day.

Some of it has come back out as open source. The deployment tooling we first wrote here became drevops/git-artifact(Opens in a new tab/window). And the practice of shipping the development database inside a Docker image, born on this platform so every developer and pipeline starts from real data, grew into drevops/mariadb-drupal-data(Opens in a new tab/window).

9 years, continuous, across 3 generations of architecture. In a market where suppliers rotate every couple of years, that is the outcome we are proudest of.

For web estates that outlive their suppliers

Everything on this page is 4 of our services running on one university estate: development alongside an in-house team, migration of content and of whole platforms, DevOps and hosting, and the training and handover that leaves the knowledge inside the client's team.

If you run a university, a TAFE or another estate that has to keep serving while it changes underneath, this is the shape the engagement takes: specialists who arrive for the peaks, a rolling upgrade programme instead of a rebuild, migrations rehearsed against the real content, and the knowledge left with your own team. The same engineering is available with AI-assisted delivery where the work suits it, at the same tested standard.

If your estate has a Drupal site heading toward end of life, or content sitting in a separate site that should not have one any more, tell us what is on the platform.