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

PHPUnit

Behat Steps, ready-made Behat test steps for Drupal

The tests every Drupal project writes twice: logins, content, email, logs

Automated tests for a website are usually written in near-English, a sentence per action. "Given I am logged in as a user with the administrator role." "Then an email should be sent to the applicant."

That is deliberate: the people who decide what a site must do can read what is being checked.

Behind each of those sentences sits real code. Someone has to implement, in PHP, what "logged in as an administrator" means, what counts as an email being sent, and how a test knows a file actually downloaded.

And the sentences repeat from project to project:

  • sign in as a role
  • create content
  • check an email went out
  • confirm nothing landed in the site's error log

Writing them the first time costs a few days. Keeping them is the part nobody budgets for.

They live in your repository, and they need attention every time Drupal(Opens in a new tab/window) moves. They are never what your project is actually about, and when they break, testing quietly stops.

A library you take a piece at a time: Behat steps as PHP traits

behat-steps(Opens in a new tab/window) is that set of steps, written once, tested and maintained. It ships as PHP traits, so a project imports the pieces it wants and nothing else.

Take the email assertions without inheriting anything you did not ask for, and keep every step your team has already written sitting alongside them.

Small parts rather than a single base class is what makes the library safe to adopt gradually. You add a piece, nothing you had before changes, and you decide about the rest later.

It covers the common ground of Drupal testing:

  • authentication and roles
  • content
  • email
  • file downloads
  • media
  • error-log checks

For a client, that reads as a shorter start: the test suite on your project begins with the common ground already written and already maintained.

Where it came from: a Drupal test context cut from 300 lines to 46

It started on a real project in 2018, a Victorian government health department website reached through a government digital agency.

That project had built itself a thorough set of test steps:

  • email assertions
  • file downloads
  • media handling
  • error-log checks

All of it solid work, and none of it specific to a health department.

So we pulled the generic parts out into a package we would maintain. The project's own test class went from roughly 300 lines of bespoke step definitions to 46 lines that simply compose the imported ones, with every check it had before still in place.

The department kept its coverage and stopped owning the plumbing underneath it. Every project we have worked on since has had those steps for free.

The decisions that make it safe to rely on: strict error-log checks

A library like this earns trust in the details. Checking Drupal's error log after every scenario is the classic source of false alarms, because some scenarios are supposed to trigger an error.

The easy answer is to soften the check for everyone. Instead, a test can declare that it expects an error, so the check stays strict everywhere else.

Sometimes the behaviour that needs adjusting sits further upstream, in the shared Drupal testing driver the library builds on. When that is the right home for a fix, it goes there rather than being worked around on every project, and we have been contributing to that driver for years.

Where it ended up: whole-of-government Victoria and community radio

A library extracted from a single health department project went on to underpin the Victorian Government's Single Digital Presence, the shared platform behind vic.gov.au and the agency sites around it. Years later it was doing the same job on a community radio station's rebuild.

It ships as part of Vortex(Opens in a new tab/window), our open-source Drupal project template, so every project we start inherits it.

It has been maintained since 2018, across Drupal 7 through to Drupal 11, which is a long time for a package to stay useful in a platform that changes as much as Drupal does.

300 lines of test glue became 46 lines of composition, and a package maintained since 2018 across Drupal 7 to Drupal 11.

It also carries contributions from developers with no connection to DrevOps. People do not send patches to code they are not depending on.

For a client, that track record is the point: the steps your suite depends on have outlived the projects that introduced them.

What it adds up to: Drupal testing that starts already built

The library is public, so any Drupal team can use it without ever talking to us. Testing gets skipped when it is expensive to start, and the quickest way to make it cheap is to stop asking every project to rebuild the same foundations.

When we take on a platform, that groundwork is already done and maintained. The effort goes into the parts that are actually yours.

For teams rewriting the same Drupal test steps

Everything on this page is 2 of our services pointed at our own tooling: development of the library, and the ongoing support and maintenance that has kept it current from Drupal 7 through to Drupal 11. The same standard applies to our AI-assisted delivery: however fast the code arrives, the automated checks are what decide it is safe to ship.

If you run a Drupal site whose test suite nobody wants to open, or a team writing the same step definitions on every new project, this is the shape the engagement takes. The generic steps come from a maintained library, your own steps sit beside them, and the only checks you own are the ones specific to your business.

If your last Drupal upgrade was verified by hand because nobody trusts the automated suite, tell us what it covers today.

Victorian Department of Health and Human Services websites

When a website is where people go for health, housing and concessions

People arrive at a health and human services website with a real question, often at a difficult moment:

  • someone checking whether they qualify for a concession
  • a parent trying to understand a family service
  • a nurse looking up clinical guidance
  • an adult asking for the records of their own childhood in care

The site either answers the question or it does not.

The Victorian Department of Health and Human Services ran one of the largest web estates in the state, covering consumer health information, concessions, housing, disability, family services, records access, and clinical guidance for the health sector. Many audiences, many editorial teams, one shared expectation that the information will be right and reachable.

Drupal engineering inside the Salsa Digital partnership

The work reached us through Salsa Digital(Opens in a new tab/window), a government digital agency whose teams carried strategy, design and content across the department's properties. We joined as their engineering partner and stayed for 4 years, providing:

Some of it was new architecture. A lot of it was the quieter work of making several teams' releases predictable.

Several audiences, one Drupal codebase and one content platform

3 of the department's public websites, serving citizens, funded organisations and service providers, were consolidated into a single Drupal codebase. One map of the estate drives everything downstream: the build, each site's settings, deployment, the test suite and the theme. Each site keeps its own visual identity through configuration rather than code, so an editorial team can change how their site looks without waiting for a developer release.

A separate content platform then decoupled the department's content from its presentation, so several front ends could share one editorial spine. It carried a consumer health encyclopaedia, professional guidance published as open data, service directories with eligibility and access details, and a records access service. Editors describe intent, such as whether a page offers text to speech or a printable version, and each front end decides how to honour it.

Built for the people on the other end: accessibility and a link-safe migration

The front ends built on that platform are server-rendered JavaScript applications, and 2 things matter about how they behave. Every part of a page is assembled independently, so one troublesome component degrades on its own instead of taking the page with it.

The second is accessibility, treated as implementation rather than aspiration:

  • screen-reader headings
  • focus management on dialogs
  • proper tab and panel semantics for medical citations
  • built-in text to speech

Migration mattered for the same reason. People bookmark government pages, print them, cite them in letters and share them in community groups, and search engines have years of them indexed.

The migration was built so those links survived: content from the legacy system was rebuilt as structured, reusable page components, and old-style page and document addresses were resolved on the new platform and served the right file. For a client, that is what a link-safe migration buys: the address saved in a bookmark or printed in a letter still leads somewhere after launch day.

Built once, released safely: containers and continuous integration

Underneath all of it we changed how the code was built and shipped. In 6 days in 2018, a live government Drupal site moved onto containers and managed dependencies, with the application built exactly once, in continuous integration, and that identical build used everywhere afterwards.

One self-documenting set of commands ran it, so every developer and the pipeline did the same thing. Releases were designed to fail quietly: a dry run by default, and a release that did not complete cleanly left visitors seeing the site exactly as it was. For a client, that is what a safe release means: a release that does not land costs you a wait, not a broken site.

What it left behind: 2 open-source tools still shipping

We worked across 4 of the department's properties over 4 years, and the tooling outlived the engagement.

2 things that began as answers to real problems on these sites are open source today and still maintained. drevops/behat-steps(Opens in a new tab/window), a library of reusable automated test steps for Drupal, was extracted from the department's sport and recreation site and later became a dependency of the Victorian Government's central content platform.

And the containerised project template built in that week in 2018 is the direct ancestor of Vortex(Opens in a new tab/window), the open-source Drupal project template we ship on every project today.

4 properties over 4 years, and 2 of the tools built for them are open source and maintained today.

That is the part we are proudest of: solving a real problem twice, then giving the answer away.

For government estates where the information has to be right

Everything on this page is 4 of our services running across one government web estate: architecture and development on a shared Drupal codebase, content migration that keeps the addresses people already have, build and release engineering, and accessibility built in rather than bolted on.

If you run a government web estate, a health service, or several public sites that share one editorial team, this is the shape the engagement takes: one codebase behind several sites, migrations that keep existing addresses resolving, and releases safe enough to be routine. The same engineering is available with AI-assisted delivery where it suits the work, at the same tested standard.

If your estate has spread across several ageing sites, or a migration is coming and the links people already have worry you, tell us what the estate looks like.

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.

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.