14 Apr 2026

feedDjango community aggregator: Community blog posts

Representing 'Jobs to be Done' in a project

I have had this idea/theory for a while, that most software tools would benefit from a simple built in todo list built into the product directly. The main idea is for users to create jobs themselves or for the system itself to create jobs for the user to complete. The general thesis for this idea comes from a direct reference to the term "Jobs to be done". Any piece of software that gets used, exists to complete a job and do it better than the solution before it.

Well over the last couple of months I have turned this idea into a reality inside Hamilton Rock, or at least the first version of it and so far it seems very promising. The general API design is a few custom signals, a model and some signal reciever functions for the custom signals. The rest of the project interacts solely through the custom signals job_requested and job_completed. Each does as you would expect, job_requested requests a job be created, job_completed complete the related job to the model instance given. The core of the job model has a status, type and a generic foreign key which forms the target related to the job. Jobs can auto-completed when a condition has been met, it's just a matter of firing off the completed signal. Example stub of the API is below.

job_requested = Signal()
job_completed = Signal()

class Job(models.Model):
    content_type = models.ForeignKey(
        ContentType,
        on_delete=models.CASCADE,
        help_text=_("The type of object this job is related to"),
    )
    object_id = models.PositiveIntegerField(
        help_text=_("The ID of the related object"),
    )
    target = GenericForeignKey("content_type", "object_id")
    
    assigned_to = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="assigned_jobs",
        help_text=_("User this job is assigned to (default notification recipient)"),
    )
    
    job_type = models.CharField(
        max_length=50,
        choices=jobTypeChoices.choices,
        help_text=_("The type of job"),
    )
    
    status = models.CharField(
        max_length=20,
        choices=StatusChoices.choices,
        default=StatusChoices.PENDING,
        db_index=True,
        help_text=_("Current status of the job"),
    )
    created_at = models.DateTimeField(
        null=True,
        blank=True,
        help_text=_("When the job was completed or cancelled"),
    ) 
    updated_at = models.DateTimeField(
        null=True,
        blank=True,
        help_text=_("When the job was completed or cancelled"),
    ) 
    completed_at = models.DateTimeField(
        null=True,
        blank=True,
        help_text=_("When the job was completed or cancelled"),
    )
    expires_at = models.DateTimeField(
        null=True,
        blank=True,
        db_index=True,
        help_text=_("When this job should be auto-cancelled if still pending"),
    )
    metadata = models.JSONField(
        default=dict,
        blank=True,
        help_text=_("Additional job-specific data"),
    )
    
@receiver(job_requested)
def handle_job_requested(  # NOQA: PLR0913
    sender,
    target,
    job_type,
    metadata=None,
    idempotent=False,
    assigned_to=None,
    **kwargs,
):
    # Creates a Job
    pass
    
@receiver(task_completed)
def handle_task_completed(sender, target, task_type, metadata=None, **kwargs):
    # Completes a Job
    pass

Currently all jobs are created by the system and we have yet to directly expose them to our users, however there have been two interesting insights from where I have used them to date (onboarding & staff pages). First in onboarding it has created a flexible way to add/remove steps for me as a developer and given that completing a job is part of the internal state rather than just a custom form or series of forms, the logic to visualise where users are stalling in our flow becomes easy to visualise. It's how many pending jobs at each step and how long have they been pending?

Second when an handled exception case occurs in the application which requires the attention of a staff user, instead of a log statement needing to be processed by some system and being perhaps overfilled with extra context, or there being extra noise in a developer tool such as Sentry, we simply create a job of the type we need. Then create a staff page to list and handle jobs of this type.

Finally this jobs architecture has enabled a central point to control how we send notifications (emails etc) from the system. Every notification is linked to a Job, which then means it forces notifications to not deal with too many actions at a time and again allows a natural tracking of which notifications have been actioned or not.

In future, I'm likely to expose these jobs to our users more directly, giving them a native solution to spend just the right amount of time in our product and no more, so what we build is simple & useful.

What do you think? Would you like this as a package for you to play with? Let me know and I may just break it out and release it!

14 Apr 2026 5:00am GMT

13 Apr 2026

feedDjango community aggregator: Community blog posts

Built with Django Weekly Roundup: Mar 23 to Apr 13

Hey, Happy Monday!

Why are you getting this: You signed up to receive this newsletter on Built with Django. I share recent projects, jobs, and useful Django links. If you no longer want this, you can unsubscribe anytime.

News and Updates

Sponsor

This issue is sponsored by TuxSEO, your content team on auto-pilot.

Generate SEO-focused content briefs and drafts faster, and ship consistently without the usual content bottlenecks.

Projects

Jobs

From the Community

Support

You can support this project by using one of the affiliate links below. These are always going to be projects I use and love! No "Bluehost" crap here!

13 Apr 2026 6:00pm GMT

feedPlanet Python

Python Software Foundation: Reflecting on Five Years as the PSF’s First CPython Developer in Residence

After nearly five wonderful years at the Python Software Foundation as the inaugural CPython Developer in Residence, it's time for me to move on. I feel honored and honestly so lucky to have had the opportunity to kick off the program that now includes several wonderful full-time engineers. I'm glad to see the program left in good hands. The vacancy created by my departure will be filled after PyCon US as the PSF is currently focused on delivering a strong event. I'm happy to share that Meta will continue to sponsor the CPython Developer in Residence role at least through mid-2027. The program is safe.

Łukasz with PSF's Security Developer in Residence Seth Larson and PyPI Safety & Security Engineer Mike Fielder at PyCon US 2025


As a member of the Python Steering Council during Łukasz's tenure as Developer in Residence, I express my personal gratitude for his dedication to the CPython project and the larger Python community. I know I echo the sentiment of everyone who has served on the Council during his time as DiR. He has defined what it means to be a Developer in Residence - a position that is incredibly important to the smooth operation of the CPython project, in large and small ways, visible and hidden. Our bi-weekly meetings gave the Steering Council a detailed, unique, and invaluable contemporaneous perspective on what's happening in CPython. Łukasz leaves big shoes to fill, and we wish him all the best in his next endeavor. It's comforting to know that he will continue to be a Python leader and member of the core team.


-- Barry Warsaw; Python Steering Council member 2026


In my time as a developer in residence, I personally touched some pretty amazing projects like the transition to GitHub issues from bugs.python.org, the replacement of the mostly manual CLA process with an automated system, the introduction of free threading to Python, and the replacement of the interactive shell in the interpreter. And between the thousands of pull requests I've reviewed or authored, and the many less glamorous tasks like content moderation and keeping the lights on when it comes to core workflow, I've interacted with some amazing individuals. Some of them are core developers now. I've witnessed the full-time paid developer in residence roster at the Python Software Foundation grow from one person to five.


As for me, ever since seeing it for the first time in 2013, I had dreamed about moving permanently to Vancouver BC. This dream is coming true soon. As part of that move, I'm joining Meta as a software engineer on the Python Language Foundation team. In any case, I'm not disappearing from the open-source Python community. I'll be seeing you online and maybe even in person at Python-related conferences.


13 Apr 2026 2:01pm GMT

Real Python: How to Add Features to a Python Project With Codex CLI

After reading this guide, you'll be able to use Codex CLI to add features to a Python project directly from your terminal. Codex CLI is an AI-powered coding assistant that runs inside your terminal. It understands your project structure, reads your files, and proposes multi-file changes using natural language instructions.

Instead of copying code from a browser or relying on an IDE plugin, you'll use Codex CLI to implement a real feature in a multi-file Python project directly from your terminal:

Example of Using Codex CLI to Implement a Project Feature

In the following steps, you'll install and configure Codex CLI, use it to implement a deletion feature in a contact book app, and then refine that feature through iterative prompting.

Take the Quiz: Test your knowledge with our interactive "How to Add Features to a Python Project With Codex CLI" quiz. You'll receive a score upon completion to help you track your learning progress:


A person standing next to a machine labeled Codex CLI that processes code through a conveyor belt, with a terminal screen, colorful blocks, and buttons labeled Add, Delete, and Clear All.

Interactive Quiz

How to Add Features to a Python Project With Codex CLI

Test your knowledge of Codex CLI, the AI-powered terminal tool for adding features to Python projects with natural language.

Prerequisites

To follow this guide, you should be familiar with the Python language. You'll also need an OpenAI account with either a paid ChatGPT subscription or a valid API key, which you'll connect to Codex CLI once you install it. Additionally, you'll need to have Node.js installed, since Codex CLI is distributed as an npm package.

To make it easier for you to experiment with Codex CLI, download the RP Contacts project by clicking the link below:

The project RP Contacts is a text-based interface (TUI) that allows you to manage contacts directly in the terminal through a Textual app. It's an adapted version of the project from Real Python's tutorial Build a Contact Book App With Python, Textual, and SQLite. It differs from the original in that it uses uv to manage the project, and the TUI buttons Delete and Clear All haven't been implemented-that's what you'll use Codex CLI for.

Once you've downloaded the project, you want to check that you can run it. As mentioned, the project uses uv for dependency management-you can tell by the uv.lock file in the project root-so make sure you have uv installed. If you don't have uv yet, follow the official installation instructions.

Once you have uv installed and you're at the root directory of the project, you can run the project:

Shell
$ uv run rpcontacts

When you run the command rpcontacts through uv for the first time, uv will create a virtual environment, install the dependencies of your project, and start the RP Contacts TUI. If all goes well, you should see a TUI in your terminal with a couple of buttons and an empty contact listing:

Contact Book Planned Main TUI

Once the TUI opens, create some test contacts by using the Add button and filling in the form that pops up. After creating a couple of fake contacts, quit the application by pressing Q.

Finally, you'll want to initialize a Git repository at the root of your project and commit all your files:

Shell
$ git init .
$ git add .
$ git commit -m "First commit."

Codex CLI will modify your code, and you can never tell whether the changes will be good or not. Versioning your code makes it straightforward to roll back any changes made by LLMs if you don't like them.

If you want to explore other AI-powered coding tools alongside Codex CLI, Real Python's Python Coding With AI learning path brings together tutorials and video courses on AI-assisted coding, prompt engineering, and LLM development.

Step 1: Install and Configure Codex CLI

With all the accessory setup out of the way, it's now time to install Codex CLI. For that, you'll want to check the official OpenAI documentation to see the most up-to-date installation instructions. As of now, OpenAI recommends using npm:

Read the full article at https://realpython.com/codex-cli/ »


[ Improve Your Python With 🐍 Python Tricks 💌 - Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]

13 Apr 2026 2:00pm GMT

PyCon: How to Build Your PyCon US 2026 Schedule

Six Pathways Through the Talks

Finding your way through three days of world-class Python content

PyCon US 2026 runs May 13-19 in Long Beach, California, and with over 100 talks across five rooms over three days, the schedule can feel like a lot to navigate. The good news: whether you came to go deep on Python performance, level up your security knowledge, get practical Python insights for agentic AI, or finally understand what all the async fuss is about, there's a clear path through the content that's built for you. Register now to get in on the full experience.

We mapped six attendee pathways through the full talks schedule with a bonus tutorial to pair with it, each one a curated sequence of sessions that focuses on a core Python topic. Think of them less as tracks and more as through-lines. Pick the one that matches where you are and what you want to walk away with to integrate into your work.

Python Performance: From Memory to Metal

If you want to understand why your Python is slow and what to actually do about it, this is your path. It runs across all three days and takes you from memory profiling fundamentals all the way to CPython internals with one of the core developers who is actually changing the way the runtime works.

Friday

Saturday

Sunday

Pair it with a tutorial: Start the week with Arthur Pastel and Adrien Cacciaguerra's Wednesday tutorial Python Performance Lab: Sharpening Your Instincts. It's a hands-on lab designed to build the kind of performance intuition that makes everything in this pathway land harder.

Debugging and Observability: Finding What's Wrong and Why

This pathway is for engineers who spend too much time in production fires and want better tools for preventing and diagnosing them. It moves from memory leak storytelling through the brand new profiling and debugging interfaces, landing in Python 3.14 and 3.15.

Friday

Saturday

Pair it with a tutorial: Catherine Nelson and Robert Masson's Thursday tutorial Going from Notebooks to Production Code is a natural warm-up, it covers the gap between exploratory code and production systems, which is exactly where most debugging pain lives.

Concurrency and Async: Making Python Do More at Once

The concurrency story in Python is changing faster than it has in years. This pathway traces the thread from hardware-level parallelism through the GIL removal to practical async patterns for the systems people are actually building in 2026.

Friday

Saturday

Pair it with a tutorial: Trey Hunner's Wednesday tutorial Lazy Looping in Practice: Building and Using Generators and Iterators is a perfect primer. Generators and iterators are the building blocks of Python's async model, and Hunner is one of the best teachers in the community at making these concepts click.

AI and Machine Learning: From Inference to Agents

The dedicated Future of AI with Python track runs all day Friday, May 15th, and it's one of the strongest single-day lineups in the schedule. This pathway threads the AI content across the full conference, from hardware fundamentals to production-grade inference.

Friday

Saturday

Pair it with a tutorial: Two tutorials are worth your attention here. Pamela Fox's Wednesday Build Your First MCP Server in Python is the fastest way to understand how agentic systems actually work under the hood - MCP is quickly becoming the standard way to give AI agents access to tools and data. And Isabel Michel's Wednesday Implementing RAG in Python: Build a Retrieval-Augmented Generation System gives you the hands-on foundation underneath most modern LLM applications.

Security: A Full Day Worth Taking Seriously

Saturday, May 16th, is the first-ever dedicated security track at PyCon US, and if security is anywhere near your professional concerns, you should plan to spend most of Saturday in Room 103ABC. Eleven experts. One room. A full day.

Saturday

Pair it with a tutorial: Paul Zuradzki's Wednesday tutorial, Practical Software Testing with Python is a strong complement: the discipline of writing tests and the discipline of writing secure code overlap more than most developers realize, and this tutorial gives you the testing foundation that makes security practices easier to implement and verify.

New to Python and Packaging: A First-Timer's Path Through the Conference

Not every pathway is about going deep. This one is for attendees who are newer to Python or who want to level up on tooling, packaging, and writing code that other people can actually use. It runs gently across all three days and ends with a satisfying arc.

Friday

Saturday

Sunday

Pair it with a tutorial: Mason Egger's Thursday tutorial, Writing Pythonic Code: Features That Make Python Powerful, is the ideal warm-up for this entire pathway. It covers the idioms and language features that separate code that works from code that feels like Python, which is exactly the mindset the rest of this track builds on. Or if you are just getting started with no experience at all, try Python for Absolute Beginners. If you've started and stopped learning to code before, or never got around to starting at all, sign up for this tutorial and start PyCon on a strong step.

However you come to PyCon US 2026, there's a path through the schedule built for you. The full talks schedule is at us.pycon.org/2026/schedule/talks, the full tutorials schedule is at https://us.pycon.org/2026/schedule/tutorials/, and registration is open now.

We'll see you in Long Beach.


PyCon US 2026 takes place May 13-19 in Long Beach, California. Talks run Friday, May 15th, through Sunday, May 17th.


13 Apr 2026 12:21pm GMT

11 Apr 2026

feedDjango community aggregator: Community blog posts

djust 0.4.0 — The Developer Experience Release

djust 0.4.0 ships 30+ features focused on developer experience: flash messages, keyboard shortcuts, form recovery, scaffolding generators, debug tooling, and security hardening. Build real-time Django apps with less code than ever.

11 Apr 2026 5:00pm GMT

04 Apr 2026

feedPlanet Twisted

Donovan Preston: Using osascript with terminal agents on macOS

Here is a useful trick that is unreasonably effective for simple computer use goals using modern terminal agents. On macOS, there has been a terminal osascript command since the original release of Mac OS X. All you have to do is suggest your agent use it and it can perform any application control action available in any AppleScript dictionary for any Mac app. No MCP set up or tools required at all. Agents are much more adapt at using rod terminal commands, especially ones that haven't changed in 30 years. Having a computer control interface that hasn't changed in 30 years and has extensive examples in the Internet corpus makes modern models understand how to use these tools basically Effortlessly. macOS locks down these permissions pretty heavily nowadays though, so you will have to grant the application control permission to terminal. But once you have done that, the range of possibilities for commanding applications using natural language is quite extensive. Also, for both Safari and chrome on Mac, you are going to want to turn on JavaScript over AppleScript permission. This basically allows claude or another agent to debug your web applications live for you as you are using them.In chrome, go to the view menu, developer submenu, and choose "Allow JavaScript from Apple events". In Safari, it's under the safari menu, settings, developer, "Allow JavaScript from Apple events". Then you can do something like "Hey Claude, would you Please use osascript to navigate the front chrome tab to hacker news". Once you suggest using OSA script in a session it will figure out pretty quickly what it can do with it. Of course you can ask it to do casual things like open your mail app or whatever. Then you can figure out what other things will work like please click around my web app or check the JavaScript Console for errors. Another very important tips for using modern agents is to try to practice using speech to text. I think speaking might be something like five times faster than typing. It takes a lot of time to get used to, especially after a lifetime of programming by typing, but it's a very interesting and a different experience and once you have a lot of practice It starts to to feel effortless.

04 Apr 2026 1:31pm GMT

16 Mar 2026

feedPlanet Twisted

Donovan Preston: "Start Drag" and "Drop" to select text with macOS Voice Control

I have been using macOS voice control for about three years. First it was a way to reduce pain from excessive computer use. It has been a real struggle. Decades of computer use habits with typing and the mouse are hard to overcome! Text selection manipulation commands work quite well on macOS native apps like apps written in swift or safari with an accessibly tagged webpage. However, many webpages and electron apps (Visual Studio Code) have serious problems manipulating the selection, not working at all when using "select foo" where foo is a word in the text box to select, or off by one errors when manipulating the cursor position or extending the selection. I only recently expanded my repertoire with the "start drag" and "drop" commands, previously having used "Click and hold mouse", "move cursor to x", and "release mouse". Well, now I have discovered that using "start drag x" and "drop x" makes a fantastic text selection method! This is really going to improve my speed. In the long run, I believe computer voice control in general is going to end up being faster than WIMP, but for now the awkwardly rigid command phrasing and the amount of times it misses commands or misunderstands commands still really holds it back. I've been learning the macOS Voice Control specific command set for years now and I still reach for the keyboard and mouse way too often.

16 Mar 2026 11:04am GMT

04 Mar 2026

feedPlanet Twisted

Glyph Lefkowitz: What Is Code Review For?

Humans Are Bad At Perceiving

Humans are not particularly good at catching bugs. For one thing, we get tired easily. There is some science on this, indicating that humans can't even maintain enough concentration to review more than about 400 lines of code at a time..

We have existing terms of art, in various fields, for the ways in which the human perceptual system fails to register stimuli. Perception fails when humans are distracted, tired, overloaded, or merely improperly engaged.

Each of these has implications for the fundamental limitations of code review as an engineering practice:

Never Send A Human To Do A Machine's Job

When you need to catch a category of error in your code reliably, you will need a deterministic tool to evaluate - and, thanks to our old friend "alert fatigue" above - ideally, to also remedy that type of error. These tools will relieve the need for a human to make the same repetitive checks over and over. None of them are perfect, but:

Don't blame reviewers for missing these things.

Code review should not be how you catch bugs.

What Is Code Review For, Then?

Code review is for three things.

First, code review is for catching process failures. If a reviewer has noticed a few bugs of the same type in code review, that's a sign that that type of bug is probably getting through review more often than it's getting caught. Which means it's time to figure out a way to deploy a tool or a test into CI that will reliably prevent that class of error, without requiring reviewers to be vigilant to it any more.

Second - and this is actually its more important purpose - code review is a tool for acculturation. Even if you already have good tools, good processes, and good documentation, new members of the team won't necessarily know about those things. Code review is an opportunity for older members of the team to introduce newer ones to existing tools, patterns, or areas of responsibility. If you're building an observer pattern, you might not realize that the codebase you're working in already has an existing idiom for doing that, so you wouldn't even think to search for it, but someone else who has worked more with the code might know about it and help you avoid repetition.

You will notice that I carefully avoided saying "junior" or "senior" in that paragraph. Sometimes the newer team member is actually more senior. But also, the acculturation goes both ways. This is the third thing that code review is for: disrupting your team's culture and avoiding stagnation. If you have new talent, a fresh perspective can also be an extremely valuable tool for building a healthy culture. If you're new to a team and trying to build something with an observer pattern, and this codebase has no tools for that, but your last job did, and it used one from an open source library, that is a good thing to point out in a review as well. It's an opportunity to spot areas for improvement to culture, as much as it is to spot areas for improvement to process.

Thus, code review should be as hierarchically flat as possible. If the goal of code review were to spot bugs, it would make sense to reserve the ability to review code to only the most senior, detail-oriented, rigorous engineers in the organization. But most teams already know that that's a recipe for brittleness, stagnation and bottlenecks. Thus, even though we know that not everyone on the team will be equally good at spotting bugs, it is very common in most teams to allow anyone past some fairly low minimum seniority bar to do reviews, often as low as "everyone on the team who has finished onboarding".

Oops, Surprise, This Post Is Actually About LLMs Again

Sigh. I'm as disappointed as you are, but there are no two ways about it: LLM code generators are everywhere now, and we need to talk about how to deal with them. Thus, an important corollary of this understanding that code review is a social activity, is that LLMs are not social actors, thus you cannot rely on code review to inspect their output.

My own personal preference would be to eschew their use entirely, but in the spirit of harm reduction, if you're going to use LLMs to generate code, you need to remember the ways in which LLMs are not like human beings.

When you relate to a human colleague, you will expect that:

  1. you can make decisions about what to focus on based on their level of experience and areas of expertise to know what problems to focus on; from a late-career colleague you might be looking for bad habits held over from legacy programming languages; from an earlier-career colleague you might be focused more on logical test-coverage gaps,
  2. and, they will learn from repeated interactions so that you can gradually focus less on a specific type of problem once you have seen that they've learned how to address it,

With an LLM, by contrast, while errors can certainly be biased a bit by the prompt from the engineer and pre-prompts that might exist in the repository, the types of errors that the LLM will make are somewhat more uniformly distributed across the experience range.

You will still find supposedly extremely sophisticated LLMs making extremely common mistakes, specifically because they are common, and thus appear frequently in the training data.

The LLM also can't really learn. An intuitive response to this problem is to simply continue adding more and more instructions to its pre-prompt, treating that text file as its "memory", but that just doesn't work, and probably never will. The problem - "context rot" is somewhat fundamental to the nature of the technology.

Thus, code-generators must be treated more adversarially than you would a human code review partner. When you notice it making errors, you always have to add tests to a mechanical, deterministic harness that will evaluates the code, because the LLM cannot meaningfully learn from its mistakes outside a very small context window in the way that a human would, so giving it feedback is unhelpful. Asking it to just generate the code again still requires you to review it all again, and as we have previously learned, you, a human, cannot review more than 400 lines at once.

To Sum Up

Code review is a social process, and you should treat it as such. When you're reviewing code from humans, share knowledge and encouragement as much as you share bugs or unmet technical requirements.

If you must reviewing code from an LLM, strengthen your automated code-quality verification tooling and make sure that its agentic loop will fail on its own when those quality checks fail immediately next time. Do not fall into the trap of appealing to its feelings, knowledge, or experience, because it doesn't have any of those things.

But for both humans and LLMs, do not fall into the trap of thinking that your code review process is catching your bugs. That's not its job.

Acknowledgments

Thank you to my patrons who are supporting my writing on this blog. If you like what you've read here and you'd like to read more of it, or you'd like to support my various open-source endeavors, you can support my work as a sponsor!

04 Mar 2026 5:24am GMT

22 Jan 2026

feedPlanet Plone - Where Developers And Integrators Write

Maurits van Rees: Mikel Larreategi: How we deploy cookieplone based projects.

We saw that cookieplone was coming up, and Docker, and as game changer uv making the installation of Python packages much faster.

With cookieplone you get a monorepo, with folders for backend, frontend, and devops. devops contains scripts to setup the server and deploy to it. Our sysadmins already had some other scripts. So we needed to integrate that.

First idea: let's fork it. Create our own copy of cookieplone. I explained this in my World Plone Day talk earlier this year. But cookieplone was changing a lot, so it was hard to keep our copy updated.

Maik Derstappen showed me copier, yet another templating language. Our idea: create a cookieplone project, and then use copier to modify it.

What about the deployment? We are on GitLab. We host our runners. We use the docker-in-docker service. We develop on a branch and create a merge request (pull request in GitHub terms). This activates a piple to check-test-and-build. When it is merged, bump the version, use release-it.

Then we create deploy keys and tokens. We give these access to private GitLab repositories. We need some changes to SSH key management in pipelines, according to our sysadmins.

For deployment on the server: we do not yet have automatic deployments. We did not want to go too fast. We are testing the current pipelines and process, see if they work properly. In the future we can think about automating deployment. We just ssh to the server, and perform some commands there with docker.

Future improvements:

  • Start the docker containers and curl/wget the /ok endpoint.
  • lock files for the backend, with pip/uv.

22 Jan 2026 9:43am GMT

Maurits van Rees: Jakob Kahl and Erico Andrei: Flying from one Plone version to another

This is a talk about migrating from Plone 4 to 6 with the newest toolset.

There are several challenges when doing Plone migrations:

  • Highly customized source instances: custom workflow, add-ons, not all of them with versions that worked on Plone 6.
  • Complex data structures. For example a Folder with a Link as default page, with pointed to some other content which meanwhile had been moved.
  • Migrating Classic UI to Volto
  • Also, you might be migrating from a completely different CMS to Plone.

How do we do migrations in Plone in general?

  • In place migrations. Run migration steps on the source instance itself. Use the standard upgrade steps from Plone. Suitable for smaller sites with not so much complexity. Especially suitable if you do only a small Plone version update.
  • Export - import migrations. You extract data from the source, transform it, and load the structure in the new site. You transform the data outside of the source instance. Suitable for all kinds of migrations. Very safe approach: only once you are sure everything is fine, do you switch over to the newly migrated site. Can be more time consuming.

Let's look at export/import, which has three parts:

  • Extraction: you had collective.jsonify, transmogrifier, and now collective.exportimport and plone.exportimport.
  • Transformation: transmogrifier, collective.exportimport, and new: collective.transmute.
  • Load: Transmogrifier, collective.exportimport, plone.exportimport.

Transmogrifier is old, we won't talk about it now. collective.exportimport: written by Philip Bauer mostly. There is an @@export_all view, and then @@import_all to import it.

collective.transmute is a new tool. This is made to transform data from collective.exportimport to the plone.exportimport format. Potentially it can be used for other migrations as well. Highly customizable and extensible. Tested by pytest. It is standalone software with a nice CLI. No dependency on Plone packages.

Another tool: collective.html2blocks. This is a lightweight Python replacement for the JavaScript Blocks conversion tool. This is extensible and tested.

Lastly plone.exportimport. This is a stripped down version of collective.exportimport. This focuses on extract and load. No transforms. So this is best suited for importing to a Plone site with the same version.

collective.transmute is in alpha, probably a 1.0.0 release in the next weeks. Still missing quite some documentation. Test coverage needs some improvements. You can contribute with PRs, issues, docs.

22 Jan 2026 9:43am GMT

Maurits van Rees: Fred van Dijk: Behind the screens: the state and direction of Plone community IT

This is a talk I did not want to give.

I am team lead of the Plone Admin team, and work at kitconcept.

The current state: see the keynotes, lots happening on the frontend. Good.

The current state of our IT: very troubling and daunting.

This is not a 'blame game'. But focussing on resources and people this conference should be a first priority. We are a real volunteer organisation, nobody is pushing anybody around. That is a strength, but also a weakness. We also see that in the Admin team.

The Admin team is 4 senior Plonistas as allround admin, 2 release managers, 2 CI/CD experts. 3 former board members, everyone overburdened with work. We had all kinds of plans for this year, but we have mostly been putting out fires.

We are a volunteer organisation, and don't have a big company behind us that can throw money at the problems. Strength and weakness. In all society it is a problem that volunteers are decreasing.

Root causes:

  • We failed to scale down in time in our IT landscape and usage.
  • We have no clean role descriptions, team descriptions, we can't ask a minimum effort per week or month.
  • The trend is more communication channels, platforms to join and promote yourself, apps to use.

Overview of what have have to keep running as admin team:

  • Support main development process: github, CI/CD, Jenkins main and runners, dist.plone.org.
  • Main communication, documentation: pone.org, docs.plone.org, training.plone.org, conf and country sites, Matomo.
  • Community office automation: Google docds, workspacae, Quaive, Signal, Slack
  • Broader: Discourse and Discord

The first two are really needed, the second we already have some problems with.

Some services are self hosted, but also a lot of SAAS services/platforms. In all, it is quite a bit.

The Admin team does not officially support all of these, but it does provide fallback support. It is too much for the current team.

There are plans for what we can improve in the short term. Thank you to a lot of people that I have already talked to about this. 3 areas: GitHub setup and config, Google Workspace, user management.

On GitHub we have a sponsored OSS plan. So we have extra features for free, but it not enough by far. User management: hard to get people out. You can't contact your members directly. E-mail has been removed, for privacy. Features get added on GitHub, and no complete changelog.

Challenge on GitHub: we have public repositories, but we also have our deployments in there. Only really secure would be private repositories, otherwise the danger is that credentials or secret could get stolen. Every developer with access becomes an attack vector. Auditing is available for only 6 months. A simple question like: who has been active for the last 2 years? No, can't do.

Some actionable items on GitHub:

  • We will separate the contributor agreement check from the organisation membership. We create a hidden team for those who signed, and use that in the check.
  • Cleanup users, use Contributors team, Developers
  • Active members: check who has contributed the last years.
  • There have been security incidents. Someone accidentally removed a few repositories. Someone's account got hacked, luckily discovered within a few hours, and some actions had already been taken.
  • More fine grained teams to control repository access.
  • Use of GitHub Discussions for some central communication of changes.
  • Use project management better.
  • The elephant in the room that we have practice on this year, and ongoing: the Collective organisation. This was free for all, very nice, but the development world is not a nice and safe place anymore. So we already needed to lock down some things there.
  • Keep deployments and the secrets all out of GitHub, so no secrets can be stolen.

Google Workspace:

  • We are dependent on this.
  • No user management. Admins have had access because they were on the board, but they kept access after leaving the board. So remove most inactive users.
  • Spam and moderation issues
  • We could move to Google docs for all kinds of things. Use Google workspace drives for all things. But the Drive UI is a mess, so docs can be in your personal account without you realizing it.

User management:

  • We need separate standalone user management, but implementation is not clear.
  • We cannot contact our members one on one.

Oh yes, Plone websites:

  • upgrade plone.org
  • self preservation: I know what needs to be done, and can do it, but have no time, focusing on the previous points instead.

22 Jan 2026 9:43am GMT