FLOSS Project Planets

Freexian Collaborators: Debian Contributions: SSO Authentication for jitsi.debian.social, /usr-move updates, and more! (by Utkarsh Gupta)

Planet Debian - Thu, 2024-04-11 20:00

Contributing to Debian is part of Freexian’s mission. This article covers the latest achievements of Freexian and their collaborators. All of this is made possible by organizations subscribing to our Long Term Support contracts and consulting services.

P.S. We’ve completed over a year of writing these blogs. If you have any suggestions on how to make them better or what you’d like us to cover, or any other opinions/reviews you might have, et al, please let us know by dropping an email to us. We’d be happy to hear your thoughts. :)

SSO Authentication for jitsi.debian.social, by Stefano Rivera

Debian.social’s jitsi instance has been getting some abuse by (non-Debian) people sharing sexually explicit content on the service. After playing whack-a-mole with this for a month, and shutting the instance off for another month, we opened it up again and the abuse immediately re-started.

Stefano sat down and wrote an SSO Implementation that hooks into Jitsi’s existing JWT SSO support. This requires everyone using jitsi.debian.social to have a Salsa account.

With only a little bit of effort, we could change this in future, to only require an account to open a room, and allow guests to join the call.

/usr-move, by Helmut Grohne

The biggest task this month was sending mitigation patches for all of the /usr-move issues arising from package renames due to the 2038 transition. As a result, we can now say that every affected package in unstable can either be converted with dh-sequence-movetousr or has an open bug report. The package set relevant to debootstrap except for the set that has to be uploaded concurrently has been moved to /usr and is awaiting migration. The move of coreutils happened to affect piuparts which hard codes the location of /bin/sync and received multiple updates as a result.

Miscellaneous contributions
  • Stefano Rivera uploaded a stable release update to python3.11 for bookworm, fixing a use-after-free crash.
  • Stefano uploaded a new version of python-html2text, and updated python3-defaults to build with it.
  • In support of Python 3.12, Stefano dropped distutils as a Build-Dependency from a few packages, and uploaded a complex set of patches to python-mitogen.
  • Stefano landed some merge requests to clean up dead code in dh-python, removed the flit plugin, and uploaded it.
  • Stefano uploaded new upstream versions of twisted, hatchling, python-flexmock, python-authlib, python–mitogen, python-pipx, and xonsh.
  • Stefano requested removal of a few packages supporting the Opsis HDMI2USB hardware that DebConf Video team used to use for HDMI capture, as they are not being maintained upstream. They started to FTBFS, with recent sdcc changes.
  • DebConf 24 is getting ready to open registration, Stefano spent some time fixing bugs in the website, caused by infrastructure updates.
  • Stefano reviewed all the DebConf 23 travel reimbursements, filing requests for more information from SPI where our records mismatched.
  • Stefano spun up a Wafer website for the Berlin 2024 mini DebConf.
  • Roberto C. Sánchez worked on facilitating the transfer of upstream maintenance responsibility for the dormant Shorewall project to a new team led by the current maintainer of the Shorewall packages in Debian.
  • Colin Watson fixed build failures in celery-haystack-ng, db1-compat, jsonpickle, libsdl-perl, kali, knews, openssh-ssh1, python-json-log-formatter, python-typing-extensions, trn4, vigor, and wcwidth. Some of these were related to the 64-bit time_t transition, since that involved enabling -Werror=implicit-function-declaration.
  • Colin fixed an off-by-one error in neovim, which was already causing a build failure in Ubuntu and would eventually have caused a build failure in Debian with stricter toolchain settings.
  • Colin added an sshd@.service template to openssh to help newer systemd versions make containers and VMs SSH-accessible over AF_VSOCK sockets.
  • Following the xz-utils backdoor, Colin spent some time testing and discussing OpenSSH upstream’s proposed inline systemd notification patch, since the current implementation via libsystemd was part of the attack vector used by that backdoor.
  • Utkarsh reviewed and sponsored some Go packages for Lena Voytek and Rajudev.
  • Utkarsh also helped Mitchell Dzurick with the adoption of pyparted package.
  • Helmut sent 10 patches for cross build failures.
  • Helmut partially fixed architecture cross bootstrap tooling to deal with changes in linux-libc-dev and the recent gcc-for-host changes and also fixed a 64bit-time_t FTBFS in libtextwrap.
  • Thorsten Alteholz uploaded several packages from debian-printing: cjet, lprng, rlpr and epson-inkjet-printer-escpr were affected by the newly enabled compiler switch -Werror=implicit-function-declaration. Besides fixing these serious bugs, Thorsten also worked on other bugs and could fix one or the other.
  • Carles updated simplemonitor and python-ring-doorbell packages with new upstream versions.
  • Santiago is still working on the Salsa CI MRs to adapt the build jobs so they can rely on sbuild. Current work includes adapting the images used by the build job, implementing the basic sbuild support the related jobs, and adjusting the support for experimental and *-backports releases..
    Additionally, Santiago reviewed some MR such as Make timeout action explicit in the logs and the subsequent Implement conditional timeout verbosity, and the batch of MRs included in https://salsa.debian.org/salsa-ci-team/pipeline/-/merge_requests/482.
  • Santiago also reviewed applications for the improving Salsa CI in Debian GSoC 2024 project. We received applications from four very talented candidates. The selection process is currently ongoing. A huge thanks to all of them!
  • As part of the DebConf 24 organization, Santiago has taken part in the Content team discussions.
Categories: FLOSS Project Planets

Reproducible Builds (diffoscope): diffoscope 264 released

Planet Debian - Thu, 2024-04-11 20:00

The diffoscope maintainers are pleased to announce the release of diffoscope version 264. This version includes the following changes:

[ Chris Lamb ] * Don't crash on invalid zipfiles, even if we encounter 'badness' through through the file. (Re: #1068705) [ FC (Fay) Stegerman ] * Add note when there are duplicate entries in ZIP files. (Closes: reproducible-builds/diffoscope!140) [ Vagrant Cascadian ] * Add an external tool reference for GNU Guix for zipdetails.

You find out more by visiting the project homepage.

Categories: FLOSS Project Planets

Pythonicity: GraphQL root fields

Planet Python - Thu, 2024-04-11 20:00
There is no such thing as a “root field”.

There is a common - seemingly universal - misconception that GraphQL root fields are somehow special, in both usage and implementation. The better conceptual model is that there are root types, and all types have fields. The difference is not just semantics; it leads to actual misunderstandings.

Multiple queries

A common beginner question is “can there be multiple queries in a request”. The question would be better phrased as “can multiple fields on the root query type be requested”. The answer is of course, because requesting multiple fields on a type is normal. The implementation would have to go out of its way to restrict that behavior on just the root type. The only need for further clarity would be to introduce aliases for duplicate fields.

Flat namespace

GraphQL types share a global namespace, causing conflicts when federating multiple graphs. Nothing can be done about that unless GraphQL adopts namespaces.

But many APIs design the root query type to have unnecessarily flat fields. One often sees a hierarchy of types and fields below the root, but the top-level fields resemble a loose collections of functions. Verbs at the top level; nouns the rest of the way down. This design choice appears to be in a feedback loop with the notion of “root fields”.

Even the convention of calling the root query type Query demonstrates a lack of specificity. In a service-oriented architecture, a particular service might be more narrowly defined.


Top-level mutation fields are special in one aspect: they are executed in order. This has resulted in even flatter namespaces for mutations,

mutation { createUser # executed first deleteUser }

This is not necessary, but seems widely believed that it is. Nested mutations work just fine.

mutation { user { create # executed in arbitrary order delete } }

If the underlying reason is truly execution order, the client could be explicit instead.

mutation { created: user { # executed first create } deleted: user { delete } }

There is no reason it has to influence API design.

Static methods

At the library level, the effect is top-level resolvers are implemented as functions (or static methods), whereas all other resolver are methods. This may lead to redundant or inefficient implementations, is oddly inconsistent, and is contrary to the documentation.

A resolver function receives four arguments:

obj The previous object, which for a field on the root Query type is often not used.

Sure, “often not used” by the developer of the API. That does not mean “should be unset” by the GraphQL library, but that is what has happened. Some libraries even exclude the object parameter entirely. In object-oriented libraries like strawberry, the code looks unnatural.

import strawberry @strawberry.type class Query: @strawberry.field def instance(self) -> bool | None: return None if self is None else isinstance(self, Query) schema = strawberry.Schema(Query) query = '{ instance }' schema.execute_sync(query).data {'instance': None}

Strawberry allows omitting self for this reason, creating an implicit staticmethod.

Root values

Libraries which follow the reference javascript implementation allow setting the root value explicitly.

schema.execute_sync(query, root_value=Query()).data {'instance': True}

Strawberry unofficially supports supplying an instance, but it has no effect.

schema = strawberry.Schema(Query()) schema.execute_sync(query).data {'instance': None}

And of course self can be of any type.

schema.execute_sync(query, root_value=...).data {'instance': False}

Moreover, the execute functions are for internal usage. Each library will vary in how to configure the root in a production application. Strawberry requires subclassing the application type.

import strawberry.asgi class GraphQL(strawberry.asgi.GraphQL): def __init__(self, root): super().__init__(strawberry.Schema(type(root))) self.root_value = root async def get_root_value(self, request): return self.root_value Example

Consider a more practical example where data is loaded, and clearly should not be reloaded on each request.

@strawberry.type class Dictionary: def __init__(self, source='/usr/share/dict/words'): self.words = {line.strip() for line in open(source)} @strawberry.field def is_word(self, text: str) -> bool: return text in self.words

Whether Dictionary is the query root - or attached to the query root - it should be instantiated only once. Of course it can be cached, but again there is a more natural way to write this outside the context of GraphQL.

@strawberry.type class Query: dictionary: Dictionary def __init__(self): self.dictionary = Dictionary()

Caching, context values, and root values are all clunky workarounds compared to the consistency of letting the root be Query() instead of Query. The applications which do not require this feature would never notice the difference.

The notion of “root fields” behaving as “top-level functions” has resulted in needless confusion, poorer API design, and incorrect implementations.

Categories: FLOSS Project Planets

The Drop Times: Harmony in Code: Irina Zaks' Open Source Journey

Planet Drupal - Thu, 2024-04-11 15:39
In a compelling interview, Irina Zaks, co-founder and CTO of Fibonacci Web Studio, shares insights on bridging quantum physics with web development, simplifying Drupal migrations, and advocating for open source in academia. Ahead of her Stanford WebCamp 2024 session, Irina discusses the impact of her work on the academic sector and her vision for the future of web technology.
Categories: FLOSS Project Planets

The Drop Times: Greece Spring Sprint 2024: Revitalizing the Greek Drupal Community

Planet Drupal - Thu, 2024-04-11 15:39
Witness the vibrant resurgence of the Greek Drupal Community at the Greece Spring Sprint 2024, where collaboration, camaraderie, and innovation reign supreme.
Categories: FLOSS Project Planets

Jonathan McDowell: Sorting out backup internet #1: recursive DNS

Planet Debian - Thu, 2024-04-11 13:41

I work from home these days, and my nearest office is over 100 miles away, 3 hours door to door if I travel by train (and, to be honest, probably not a lot faster given rush hour traffic if I drive). So I’m reliant on a functional internet connection in order to be able to work. I’m lucky to have access to Openreach FTTP, provided by Aquiss, but I worry about what happens if there’s a cable cut somewhere or some other long lasting problem. Worst case I could tether to my work phone, or try to find some local coworking space to use while things get sorted, but I felt like arranging a backup option was a wise move.

Step 1 turned out to be sorting out recursive DNS. It’s been many moons since I had to deal with running DNS in a production setting, and I’ve mostly done my best to avoid doing it at home too. dnsmasq has done a decent job at providing for my needs over the years, covering DHCP, DNS (+ tftp for my test device network). However I just let it slave off my ISP’s nameservers, which means if that link goes down it’ll no longer be able to resolve anything outside the house.

One option would have been to either point to a different recursive DNS server (Cloudfare’s or Google’s Public DNS being the common choices), but I’ve no desire to share my lookup information with them. As another approach I could have done some sort of failover of resolv.conf when the primary network went down, but then I would have to get into moving files around based on networking status and that felt a bit clunky.

So I decided to finally setup a proper local recursive DNS server, which is something I’ve kinda meant to do for a while but never had sufficient reason to look into. Last time I did this I did it with BIND 9 but there are more options these days, and I decided to go with unbound, which is primarily focused on recursive DNS.

One extra wrinkle, pointed out by Lars, is that having dynamic name information from DHCP hosts is exceptionally convenient. I’ve kept dnsmasq as the local DHCP server, so I wanted to be able to forward local queries there.

I’m doing all of this on my RB5009, running Debian. Installing unbound was a simple matter of apt install unbound. I needed 2 pieces of configuration over the default, one to enable recursive serving for the house networks, and one to enable forwarding of queries for the local domain to dnsmasq. I originally had specified the wildcard address for listening, but this caused problems with the fact my router has many interfaces and would sometimes respond from a different address than the request had come in on.

/etc/unbound/unbound.conf.d/network-resolver.conf server: interface: interface: 2001::db8:f00d::1 access-control: allow access-control: 2001::db8:f00d::/56 allow

/etc/unbound/unbound.conf.d/local-to-dnsmasq.conf server: domain-insecure: "example.org" do-not-query-localhost: no forward-zone: name: "example.org" forward-addr:

I then had to configure dnsmasq to not listen on port 53 (so unbound could), respond to requests on the loopback interface (I have dnsmasq restricted to only explicitly listed interfaces), and to hand out unbound as the appropriate nameserver in DHCP requests - once dnsmasq is not listening on port 53 it no longer does this by default.

/etc/dnsmasq.d/behind-unbound interface=lo port=5353 dhcp-option=option6:dns-server,[2001::db8:f00d::1] dhcp-option=option:dns-server,

With these minor changes in place I now have local recursive DNS being handled by unbound, without losing dynamic local DNS for DHCP hosts. As an added bonus I now get 10/10 on Test IPv6 - previously I was getting dinged on the ability for my DNS server to resolve purely IPv6 reachable addresses.

Next step, actually sorting out a backup link.

Categories: FLOSS Project Planets

Reproducible Builds: Reproducible Builds in March 2024

Planet Debian - Thu, 2024-04-11 12:49

Welcome to the March 2024 report from the Reproducible Builds project! In our reports, we attempt to outline what we have been up to over the past month, as well as mentioning some of the important things happening more generally in software supply-chain security. As ever, if you are interested in contributing to the project, please visit our Contribute page on our website.

Arch Linux minimal container userland now 100% reproducible

In remarkable news, Reproducible builds developer kpcyrd reported that that the Arch Linux “minimal container userland” is now 100% reproducible after work by developers dvzv and Foxboron on the one remaining package. This represents a “real world”, widely-used Linux distribution being reproducible.

Their post, which kpcyrd suffixed with the question “now what?”, continues on to outline some potential next steps, including validating whether the container image itself could be reproduced bit-for-bit. The post, which was itself a followup for an Arch Linux update earlier in the month, generated a significant number of replies.

Validating Debian’s build infrastructure after the XZ backdoor

From our mailing list this month, Vagrant Cascadian wrote about being asked about trying to perform concrete reproducibility checks for recent Debian security updates, in an attempt to gain some confidence about Debian’s build infrastructure given that they performed builds in environments running the high-profile XZ vulnerability.

Vagrant reports (with some caveats):

So far, I have not found any reproducibility issues; everything I tested I was able to get to build bit-for-bit identical with what is in the Debian archive.

That is to say, reproducibility testing permitted Vagrant and Debian to claim with some confidence that builds performed when this vulnerable version of XZ was installed were not interfered with.

Making Fedora Linux (more) reproducible

In March, Davide Cavalca gave a talk at the 2024 Southern California Linux Expo (aka SCALE 21x) about the ongoing effort to make the Fedora Linux distribution reproducible.

Documented in more detail on Fedora’s website, the talk touched on topics such as the specifics of implementing reproducible builds in Fedora, the challenges encountered, the current status and what’s coming next. (YouTube video)

Increasing Trust in the Open Source Supply Chain with Reproducible Builds and Functional Package Management

Julien Malka published a brief but interesting paper in the HAL open archive on Increasing Trust in the Open Source Supply Chain with Reproducible Builds and Functional Package Management:

Functional package managers (FPMs) and reproducible builds (R-B) are technologies and methodologies that are conceptually very different from the traditional software deployment model, and that have promising properties for software supply chain security. This thesis aims to evaluate the impact of FPMs and R-B on the security of the software supply chain and propose improvements to the FPM model to further improve trust in the open source supply chain. PDF

Julien’s paper poses a number of research questions on how the model of distributions such as GNU Guix and NixOS can “be leveraged to further improve the safety of the software supply chain”, etc.

Software and source code identification with GNU Guix and reproducible builds

In a long line of commendably detailed blog posts, Ludovic Courtès, Maxim Cournoyer, Jan Nieuwenhuizen and Simon Tournier have together published two interesting posts on the GNU Guix blog this month. In early March, Ludovic Courtès, Maxim Cournoyer, Jan Nieuwenhuizen and Simon Tournier wrote about software and source code identification and how that might be performed using Guix, rhetorically posing the questions: “What does it take to ‘identify software’? How can we tell what software is running on a machine to determine, for example, what security vulnerabilities might affect it?”

Later in the month, Ludovic Courtès wrote a solo post describing adventures on the quest for long-term reproducible deployment. Ludovic’s post touches on GNU Guix’s aim to support “time travel”, the ability to reliably (and reproducibly) revert to an earlier point in time, employing the iconic image of Harold Lloyd hanging off the clock in Safety Last! (1925) to poetically illustrate both the slapstick nature of current modern technology and the gymnastics required to navigate hazards of our own making.

Two new Rust-based tools for post-processing determinism

Zbigniew Jędrzejewski-Szmek announced add-determinism, a work-in-progress reimplementation of the Reproducible Builds project’s own strip-nondeterminism tool in the Rust programming language, intended to be used as a post-processor in RPM-based distributions such as Fedora

In addition, Yossi Kreinin published a blog post titled “refix: fast, debuggable, reproducible builds that describes a tool that post-processes binaries in such a way that they are still debuggable with gdb, etc.. Yossi post details the motivation and techniques behind the (fast) performance of the tool.

Distribution work

In Debian this month, since the testing framework no longer varies the build path, James Addison performed a bulk downgrade of the bug severity for issues filed with a level of normal to a new level of wishlist. In addition, 28 reviews of Debian packages were added, 38 were updated and 23 were removed this month adding to ever-growing knowledge about identified issues. As part of this effort, a number of issue types were updated, including Chris Lamb adding a new ocaml_include_directories toolchain issue [] and James Addison adding a new filesystem_order_in_java_jar_manifest_mf_include_resource issue [] and updating the random_uuid_in_notebooks_generated_by_nbsphinx to reference a relevant discussion thread [].

In addition, Roland Clobus posted his 24th status update of reproducible Debian ISO images. Roland highlights that the images for Debian unstable often cannot be generated due to changes in that distribution related to the 64-bit time_t transition.

Lastly, Bernhard M. Wiedemann posted another monthly update for his reproducibility work in openSUSE.

Mailing list highlights

Elsewhere on our mailing list this month:

Website updates

There were made a number of improvements to our website this month, including:

  • Pol Dellaiera noticed the frequent need to correctly cite the website itself in academic work. To facilitate easier citation across multiple formats, Pol contributed a Citation File Format (CIF) file. As a result, an export in BibTeX format is now available in the Academic Publications section. Pol encourages community contributions to further refine the CITATION.cff file. Pol also added an substantial new section to the “buy in” page documenting the role of Software Bill of Materials (SBOMs) and ephemeral development environments. [][]

  • Bernhard M. Wiedemann added a new “commandments” page to the documentation [][] and fixed some incorrect YAML elsewhere on the site [].

  • Chris Lamb add three recent academic papers to the publications page of the website. []

  • Mattia Rizzolo and Holger Levsen collaborated to add Infomaniak as a sponsor of amd64 virtual machines. [][][]

  • Roland Clobus updated the “stable outputs” page, dropping version numbers from Python documentation pages [] and noting that Python’s set data structure is also affected by the PYTHONHASHSEED functionality. []

Delta chat clients now reproducible

Delta Chat, an open source messaging application that can work over email, announced this month that the Rust-based core library underlying Delta chat application is now reproducible.


diffoscope is our in-depth and content-aware diff utility that can locate and diagnose reproducibility issues. This month, Chris Lamb made a number of changes such as uploading versions 259, 260 and 261 to Debian and made the following additional changes:

  • New features:

    • Add support for the zipdetails tool from the Perl distribution. Thanks to Fay Stegerman and Larry Doolittle et al. for the pointer and thread about this tool. []
  • Bug fixes:

    • Don’t identify Redis database dumps as GNU R database files based simply on their filename. []
    • Add a missing call to File.recognizes so we actually perform the filename check for GNU R data files. []
    • Don’t crash if we encounter an .rdb file without an equivalent .rdx file. (#1066991)
    • Correctly check for 7z being available—and not lz4—when testing 7z. []
    • Prevent a traceback when comparing a contentful .pyc file with an empty one. []
  • Testsuite improvements:

    • Fix .epub tests after supporting the new zipdetails tool. []
    • Don’t use parenthesis within test “skipping…” messages, as PyTest adds its own parenthesis. []
    • Factor out Python version checking in test_zip.py. []
    • Skip some Zip-related tests under Python 3.10.14, as a potential regression may have been backported to the 3.10.x series. []
    • Actually test 7z support in the test_7z set of tests, not the lz4 functionality. (Closes: reproducible-builds/diffoscope#359). []

In addition, Fay Stegerman updated diffoscope’s monkey patch for supporting the unusual Mozilla ZIP file format after Python’s zipfile module changed to detect potentially insecure overlapping entries within .zip files. (#362)

Chris Lamb also updated the trydiffoscope command line client, dropping a build-dependency on the deprecated python3-distutils package to fix Debian bug #1065988 [], taking a moment to also refresh the packaging to the latest Debian standards []. Finally, Vagrant Cascadian submitted an update for diffoscope version 260 in GNU Guix. []

Upstream patches

This month, we wrote a large number of patches, including:

Bernhard M. Wiedemann used reproducibility-tooling to detect and fix packages that added changes in their %check section, thus failing when built with the --no-checks option. Only half of all openSUSE packages were tested so far, but a large number of bugs were filed, including ones against caddy, exiv2, gnome-disk-utility, grisbi, gsl, itinerary, kosmindoormap, libQuotient, med-tools, plasma6-disks, pspp, python-pypuppetdb, python-urlextract, rsync, vagrant-libvirt and xsimd.

Similarly, Jean-Pierre De Jesus DIAZ employed reproducible builds techniques in order to test a proposed refactor of the ath9k-htc-firmware package. As the change produced bit-for-bit identical binaries to the previously shipped pre-built binaries:

I don’t have the hardware to test this firmware, but the build produces the same hashes for the firmware so it’s safe to say that the firmware should keep working.

Reproducibility testing framework

The Reproducible Builds project operates a comprehensive testing framework running primarily at tests.reproducible-builds.org in order to check packages and other artifacts for reproducibility.

In March, an enormous number of changes were made by Holger Levsen:

  • Debian-related changes:

    • Sleep less after a so-called “404” package state has occurred. []
    • Schedule package builds more often. [][]
    • Regenerate all our HTML indexes every hour, but only every 12h for the released suites. []
    • Create and update unstable and experimental base systems on armhf again. [][]
    • Don’t reschedule so many “depwait” packages due to the current size of the i386 architecture queue. []
    • Redefine our scheduling thresholds and amounts. []
    • Schedule untested packages with a higher priority, otherwise slow architectures cannot keep up with the experimental distribution growing. []
    • Only create the stats_buildinfo.png graph once per day. [][]
    • Reproducible Debian dashboard: refactoring, update several more static stats only every 12h. []
    • Document how to use systemctl with new systemd-based services. []
    • Temporarily disable armhf and i386 continuous integration tests in order to get some stability back. []
    • Use the deb.debian.org CDN everywhere. []
    • Remove the rsyslog logging facility on bookworm systems. []
    • Add zst to the list of packages which are false-positive diskspace issues. []
    • Detect failures to bootstrap Debian base systems. []
  • Arch Linux-related changes:

    • Temporarily disable builds because the pacman package manager is broken. [][]
    • Split reproducible_html_live_status and split the scheduling timing . [][][]
    • Improve handling when database is locked. [][]
  • Misc changes:

    • Show failed services that require manual cleanup. [][]
    • Integrate two new Infomaniak nodes. [][][][]
    • Improve IRC notifications for artifacts. []
    • Run diffoscope in different systemd slices. []
    • Run the node health check more often, as it can now repair some issues. [][]
    • Also include the string Bot in the userAgent for Git. (Re: #929013). []
    • Document increased tmpfs size on our OUSL nodes. []
    • Disable memory account for the reproducible_build service. [][]
    • Allow 10 times as many open files for the Jenkins service. []
    • Set OOMPolicy=continue and OOMScoreAdjust=-1000 for both the Jenkins and the reproducible_build service. []

Mattia Rizzolo also made the following changes:

  • Debian-related changes:

    • Define a systemd slice to group all relevant services. [][]
    • Add a bunch of quotes in scripts to assuage the shellcheck tool. []
    • Add stats on how many packages have been built today so far. []
    • Instruct systemd-run to handle diffoscope’s exit codes specially. []
    • Prefer the pgrep tool over grepping the output of ps. []
    • Re-enable a couple of i386 and armhf architecture builders. [][]
    • Fix some stylistic issues flagged by the Python flake8 tool. []
    • Cease scheduling Debian unstable and experimental on the armhf architecture due to the time_t transition. []
    • Start a few more i386 & armhf workers. [][][]
    • Temporarly skip pbuilder updates in the unstable distribution, but only on the armhf architecture. []
  • Other changes:

    • Perform some large-scale refactoring on how the systemd service operates. [][]
    • Move the list of workers into a separate file so it’s accessible to a number of scripts. []
    • Refactor the powercycle_x86_nodes.py script to use the new IONOS API and its new Python bindings. []
    • Also fix nph-logwatch after the worker changes. []
    • Do not install the stunnel tool anymore, it shouldn’t be needed by anything anymore. []
    • Move temporary directories related to Arch Linux into a single directory for clarity. []
    • Update the arm64 architecture host keys. []
    • Use a common Postfix configuration. []

The following changes were also made: by

  • Jan-Benedict Glaw:

    • Initial work to clean up a messy NetBSD-related script. [][]
  • Roland Clobus:

    • Show the installer log if the installer fails to build. []
    • Avoid the minus character (i.e. -) in a variable in order to allow for tags in openQA. []
    • Update the schedule of Debian live image builds. []
  • Vagrant Cascadian:

    • Maintenance on the virt* nodes is completed so bring them back online. []
    • Use the fully qualified domain name in configuration. []

Node maintenance was also performed by Holger Levsen, Mattia Rizzolo [][] and Vagrant Cascadian [][][][]

If you are interested in contributing to the Reproducible Builds project, please visit our Contribute page on our website. However, you can get in touch with us via:

Categories: FLOSS Project Planets

Qt for MCUs 2.5.3 LTS Released

Planet KDE - Thu, 2024-04-11 09:16

Qt for MCUs 2.5.3 LTS (Long-Term Support) has been released and is available for download. As a patch release, Qt for MCUs 2.5.3 LTS provides bug fixes and other improvements, and maintains source compatibility with Qt for MCUs 2.5.x. It does not add any new functionality.

Categories: FLOSS Project Planets

Russell Coker: ML Training License

Planet Debian - Thu, 2024-04-11 07:30

Last year a Debian Developer blogged about writing Haskell code to give a bad result for LLMs that were trained on it. I forgot who wrote the post and I’d appreciate the URL if anyone has it.

I respect such technical work to enforce one’s legal rights when they aren’t respected by corporations, but I have a different approach.

As an aside the Fosdem lecture “Fortify AI against regulation, litigation and lobotomies” is interesting on this topic [1], it’s what inspired me to write about this.

For what I write I am at this time happy to allow it to be used as part of a large training data set (consider this blog post a licence grant that applies until such time as I edit this post to change it). But only if aggregated with so much other data that my content is only a tiny portion of the data set by any metric. So I don’t want someone to make a programming LLM that has my code as the only C code or a political data set that has my blog posts as the only left-wing content. If someone wants to train an LLM on only my content to make a Russell-simulator then I don’t license my work for that purpose but also as it’s small enough that anyone with a bit of skill could do it on a weekend I can’t stop it. I would be really interested in seeing the results if someone from the FOSS community wanted to make a Russell-simulator and would probably issue them a license for such work if asked.

If my work comprises more than 0.1% of the content in a particular measure (theme, programming language, political position, etc) in a training data set then I don’t permit that without prior discussion.

Finally if someone wants to make a FOSS training data set to be used for FOSS LLM systems (maybe under the AGPL or some similar license) then I’ll allow my writing to be used as part of that.

Related posts:

  1. lemonup and blog license I have just updated my previous post about licenses and...
  2. License Fees for Music in Clubs The Cyber Law Center has blogged about the Phonographic Performance...
  3. BTRFS Training Some years ago Barwon South Water gave LUV 3 old...
Categories: FLOSS Project Planets

PyCharm: Django Learning Resources

Planet Python - Thu, 2024-04-11 06:53
Are you new to Django development? Are you already familiar with it and want to expand your knowledge? PyCharm has Django learning resources for everyone.  In this article, you’ll find a compilation of all the Django-related resources created by the experts at PyCharm to help you navigate through them all. From creating a new Django […]
Categories: FLOSS Project Planets

Wouter Verhelst: OpenSC and the Belgian eID

Planet Debian - Thu, 2024-04-11 05:33

Getting the Belgian eID to work on Linux systems should be fairly easy, although some people do struggle with it.

For that reason, there is a lot of third-party documentation out there in the form of blog posts, wiki pages, and other kinds of things. Unfortunately, some of this documentation is simply wrong. Written by people who played around with things until it kind of worked, sometimes you get a situation where something that used to work in the past (but wasn't really necessary) now stopped working, but it's still added to a number of locations as though it were the gospel.

And then people follow these instructions and now things don't work anymore.

One of these revolves around OpenSC.

OpenSC is an open source smartcard library that has support for a pretty large number of smartcards, amongst which the Belgian eID. It provides a PKCS#11 module as well as a number of supporting tools.

For those not in the know, PKCS#11 is a standardized C API for offloading cryptographic operations. It is an API that can be used when talking to a hardware cryptographic module, in order to make that module perform some actions, and it is especially popular in the open source world, with support in NSS, amongst others. This library is written and maintained by mozilla, and is a low-level cryptographic library that is used by Firefox (on all platforms it supports) as well as by Google Chrome and other browsers based on that (but only on Linux, and as I understand it, only for linking with smartcards; their BoringSSL library is used for other things).

The official eID software that we ship through eid.belgium.be, also known as "BeID", provides a PKCS#11 module for the Belgian eID, as well as a number of support tools to make interacting with the card easier, such as the "eID viewer", which provides the ability to read data from the card, and validate their signatures. While the very first public version of this eID PKCS#11 module was originally based on OpenSC, it has since been reimplemented as a PKCS#11 module in its own right, with no lineage to OpenSC whatsoever anymore.

About five years ago, the Belgian eID card was renewed. At the time, a new physical appearance was the most obvious difference with the old card, but there were also some technical, on-chip, differences that are not so apparent. The most important one here, although it is not the only one, is the fact that newer eID cards now use a NIST P-384 elliptic curve-based private keys, rather than the RSA-based ones that were used in the past. This change required some changes to any PKCS#11 module that supports the eID; both the BeID one, as well as the OpenSC card-belpic driver that is written in support of the Belgian eID.

Obviously, the required changes were implemented for the BeID module; however, the OpenSC card-belpic driver was not updated. While I did do some preliminary work on the required changes, I was unable to get it to work, and eventually other things took up my time so I never finished the implementation. If someone would like to finish the work that I started, the preliminal patch that I wrote could be a good start -- but like I said, it doesn't yet work. Also, you'll probably be interested in the official documentation of the eID card.

Unfortunately, in the mean time someone added the Applet 1.8 ATR to the card-belpic.c file, without also implementing the required changes to the driver so that the PKCS#11 driver actually supports the eID card. The result of this is that if you have OpenSC installed in NSS for either Firefox or any Chromium-based browser, and it gets picked up before the BeID PKCS#11 module, then NSS will stop looking and pass all crypto operations to the OpenSC PKCS#11 module rather than to the official eID PKCS#11 module, and things will not work at all, causing a lot of confusion.

I have therefore taken the following two steps:

  1. The official eID packages now conflict with the OpenSC PKCS#11 module. Specifically only the PKCS#11 module, not the rest of OpenSC, so you can theoretically still use its tools. This means that once we release this new version of the eID software, when you do an upgrade and you have OpenSC installed, it will remove the PKCS#11 module and anything that depends on it. This is normal and expected.
  2. I have filed a pull request against OpenSC that removes the Applet 1.8 ATR from the driver, so that OpenSC will stop claiming that it supports the 1.8 applet.

When the pull request is accepted, we will update the official eID software to make the conflict versioned, so that as soon as it works again you will again be able to install the OpenSC and BeID packages at the same time.

In the mean time, if you have the OpenSC PKCS#11 module installed on your system, and your eID authentication does not work, try removing it.

Categories: FLOSS Project Planets

LN Webworks: PHP Attributes In Drupal Development: All You Need To Know

Planet Drupal - Thu, 2024-04-11 05:22

Drupal is moving ahead with PHP attributes. Introduced in PHP 8.1, this feature is changing how developers define plugins and manage their metadata. But there’s a lot more that comes with it. 

First and foremost, PHP attributes are a native feature of PHP 8.1. It eliminates the need for external libraries like "doctrine/annotations." This simplifies the development process by keeping code clean and concise. 

Furthermore, modern IDEs offer better support for attributes. They provide features like code completion and validation, making your workflow significantly more efficient. And because attributes are a core part of the PHP language, you can rest assured that they'll receive ongoing development and support in future PHP versions. All of this ensures that your code remains compatible and up-to-date as Drupal evolves.

However, one question that comes up very often is why PHP attributes in the first place. Well, let’s understand this by knowing the limitations of annotations. 

Categories: FLOSS Project Planets

Test and Code: 217: Podcasting / SaaS / Work Life Balance - Justin Jackson

Planet Python - Thu, 2024-04-11 03:36

If you've ever thought about starting a podcast or a SaaS project, you'll want to listen to this episode.
Justin is one of the people who motivated me to get started podcasting.
He's also running a successful SaaS company, transistor.fm, which hosts this podcast.


  • Podcasting
  • Building new SaaS (software as a service) products
  • Balancing work, side hustle, and family
  • Great places to snowboard in British Columbia

BTW. This episode was recorded last summer before I switched to transistor.fm.
I'm now on Transistor for most of a year now, and I love it.

Links from the show:

Sponsored by Mailtrap.io

  • An Email Delivery Platform that developers love. 
  • An email-sending solution with industry-best analytics, SMTP, an email API, SDKs for major programming languages, and 24/7 human support. 
  • Try for Free at MAILTRAP.IO

Sponsored by PyCharm Pro

The Complete pytest Course

  • For the fastest way to learn pytest, go to courses.pythontest.com
  • Whether your new to testing or pytest, or just want to maximize your efficiency and effectiveness when testing.
<p>If you've ever thought about starting a podcast or a SaaS project, you'll want to listen to this episode.<br> <br>Justin is one of the people who motivated me to get started podcasting. <br>He's also running a successful SaaS company, <a href="https://transistor.fm/?via=okken">transistor.fm</a>, which hosts this podcast.</p><p>Topics:</p><ul><li>Podcasting</li><li>Building new SaaS (software as a service) products</li><li>Balancing work, side hustle, and family</li><li>Great places to snowboard in British Columbia</li></ul><p>BTW. This episode was recorded last summer before I switched to <a href="https://transistor.fm/?via=okken">transistor.fm</a>.<br>I'm now on Transistor for most of a year now, and I love it.</p><p>Links from the show:</p><ul><li><a href="https://transistor.fm/?via=okken">Transistor.fm</a> - excellent podcast hosting, Justin is a co-founder</li><li><a href="https://transistor.fm/how-to-start-a-podcast/?via=okken">How to start a podcast in 2024</a></li><li>Podcasts from Justin<ul><li><a href="https://saas.transistor.fm/">Build your SaaS</a> - current</li><li><a href="https://www.buildandlaunch.net/">Build &amp; Launch</a> - an older one, but great</li><li><a href="https://podcast.megamaker.co/">MegaMaker</a> - from 2021 / 2022</li></ul></li></ul> <br><p><strong>Sponsored by Mailtrap.io</strong></p><ul><li>An Email Delivery Platform that developers love. </li><li>An email-sending solution with industry-best analytics, SMTP, an email API, SDKs for major programming languages, and 24/7 human support. </li><li>Try for Free at <a href="https://l.rw.rw/pythontest">MAILTRAP.IO</a></li></ul><p><strong>Sponsored by PyCharm Pro</strong></p><ul><li>Use code PYTEST for 20% off PyCharm Professional at <a href="https://www.jetbrains.com/pycharm/">jetbrains.com/pycharm</a></li><li>Now with Full Line Code Completion</li><li>See how easy it is to run pytest from PyCharm at <a href="https://pythontest.com/pycharm/">pythontest.com/pycharm</a></li></ul><p><strong>The Complete pytest Course</strong></p><ul><li>For the fastest way to learn pytest, go to <a href="https://courses.pythontest.com/p/complete-pytest-course">courses.pythontest.com</a></li><li>Whether your new to testing or pytest, or just want to maximize your efficiency and effectiveness when testing.</li></ul>
Categories: FLOSS Project Planets

The Drop Times: 2024 Drupal Developer Survey Seeks Global Input to Shape the Future

Planet Drupal - Thu, 2024-04-11 03:19
The 2024 Drupal Developer Survey is now open, inviting developers worldwide to contribute their experiences and shape the future of Drupal. With a focus on new questions and broadened language accessibility, the survey aims to capture diverse perspectives from the global Drupal community. Results will be revealed at DrupalCon Portland 2024 and are set to influence the ecosystem's direction, benefiting contributors, tool makers, and users alike.
Categories: FLOSS Project Planets

Recursive Instantiation with Qt Quick and JSON

Planet KDE - Thu, 2024-04-11 03:00

Recently I was tasked to come up with an architecture for remote real time instantiation and updating of arbitrary QML components.

This entry shows how you can use a simple variation of the factory method pattern in QML for instantiating arbitrary components. I’ve split my findings into 3 blog entries, each one covering a slightly different topic. Part 1 focuses on the software design pattern used to dynamically instantiate components. Part 2 shows how to layout these dynamic components by incorporating QML’ s positioning and layout APIs. The last entry, consisting of Parts 3 and 4, addresses the anchors API and important safety aspects.

This is Part 1: Recursive Instantiation with Qt Quick and JSON.

The original factory method pattern made use of static methods to programmatically instantiate objects of different classes, instead of having to call their constructors. It achieved that by having the classes share a common ancestor. Our variation of the popular pattern uses a Loader to choose which component to load, and a Repeater to dynamically instantiate arbitrary instances of this loader using a model.

Here we specify which components with a JSON array and use a Repeater to load them.

id: root // A JSON representation of a QML layout: property var factoryModel: [ { "component": "Button", }, { "component": "Button", } ] // Root of our component factory Repeater { model: root.factoryModel delegate: loaderComp }

To be able to instantiate any kind of item, you can use a Component with a Loader inside, as the Repeater’s delegate. This allows you to load a different component based on the Repeater’s model data.

// Root component of the factory and nodes Component { id: loaderComp Loader { id: instantiator required property var modelData sourceComponent: switch (modelData.component) { case "Button": return buttonComp; case "RowLayout": return rowLayoutComp; case "Item": default: return itemComp; } } }

To assign values from the model to the component, add a method that gets called when the Loader’s onItemChanged event is triggered. I use this method to take care of anything that involves the component’s properties:

// Root component of the factory and nodes Component { id: loaderComp Loader { id: instantiator required property var modelData sourceComponent: switch (modelData.component) { case "Button": return buttonComp; case "RowLayout": return rowLayoutComp; case "Item": default: return itemComp; } onItemChanged: { // Pass children (see explanation below) if (typeof(modelData.children) === "object") item.model = modelData.children; // Button properties switch (modelData.component) { case "Button": // If the model contains certain value, we may assign it: if (typeof(modelData.text) !== "undefined") item.text = modelData.text; break; } // Item properties // Since Item is the parent of all repeatable, we don't need to check // if the component supports Item properties before we assign them: if (typeof(modelData.x) !== "undefined") loaderComp.x = Number(modelData.x); if (typeof(modelData.y) !== "undefined") loaderComp.y = Number(modelData.y); // ... } } }

Examples of components that loaderComp could load are defined below. To enable recursion, these components must contain a Repeater that instantiates children components, with loaderComp set as the delegate:

Component { id: itemComp Item { property alias children: itemRepeater.model children: Repeater { id: itemRepeater delegate: loaderComp } } } Component { id: buttonComp Button { property alias children: itemRepeater.model children: Repeater { id: itemRepeater delegate: loaderComp } } } Component { id: rowLayoutComp RowLayout { property alias children: itemRepeater.model children: Repeater { id: itemRepeater delegate: loaderComp } } }

The Repeater inside of the components allows us to instantiate components recursively, by having a branch or more of children components in the model, like so:

// This model lays out buttons vertically property var factoryModel: [ { "component": "RowLayout", "children": [ { "component": "Button", "text": "Button 1" }, { "component": "Button", "text": "Button 2" } ] } ]

Here we’ve seen how we can use a Repeater, a JSON model, a Loader delegate, and simple recursive definition to instantiate arbitrary QML objects from a JSON description. In my next entry I will focus on how you can lay out these arbitrarily instantiated objects on your screen.

Thanks to Kevin Krammer and Jan Marker whose insights helped improve the code you’ve seen here.

I hope you’ve found this useful! Part 2 may be found already or later by following this link.


About KDAB

If you like this article and want to read similar material, consider subscribing via our RSS feed.

Subscribe to KDAB TV for similar informative short video content.

KDAB provides market leading software consulting and development services and training in Qt, C++ and 3D/OpenGL. Contact us.

The post Recursive Instantiation with Qt Quick and JSON appeared first on KDAB.

Categories: FLOSS Project Planets

How Selenium Helps Build Sustainable Software (And More)

Planet KDE - Wed, 2024-04-10 20:00
Figure : Logo of the KDE Eco initiative. (Image from KDE published under a CC-BY-SA-4.0 license. Design by Lana Lutz.) What Is Sustainability And Why This Project?

In a general sense, sustainability refers to "the ability to maintain or support a process continuously over time". But what does it mean in terms of software?

With a rise in new technologies over the past half a century, the energy consumption of digital technology has greatly increased as well. Take, for example, large LLM models and cryptocurrency technology: both of these have heavy energy requirements. Software directly or indirectly consumes natural resources. The way software is written has a significant influence on resource consumption, such as with software-induced hardware obsolescence, when hardware vendors drive sales of new hardware through software updates that are incompatible with older hardware. The result is electronic waste and the unnecessary consumption of resources and energy in producing and transporting new hardware.

Sustainability in software means minimizing this waste. How? By designing software to limit energy consumption and have a smaller environmental impact. For this, we need tools to measure how much energy our software — and the hardware which runs it — needs. Without measurements, we cannot compare and we cannot improve!

KDE Eco has been working on KEcoLab, a project from Karanjot Singh to make KDE's measurement laboratory accessible to contributors from all over the world. KEcoLab needed a tool to easily playback usage scenarios for energy consumption data, and this is exactly what Selenium does by running automatic functional testing! But that's not all. Selenium also helps achieve the "KDE For All" goal by enabling accessibility improvements for everyone. It helps achieve the "Automate & Systematize Internal Processes" goal by creating functional tests to ensure the high quality of new code. In this way, Selenium helps achieve all three of KDE's goals!

Writing Tests In Selenium

Selenium AT-SPI is a Selenium-based tool used in KDE for automated tests of GUI applications. It works by identifying accessibility elements for a particular action. To know more about how Selenium AT-SPI functions internally, you can check out this blog post.

Writing a Selenium test is comprised of the following steps:

  • Identifying QML elements where the action needs to be performed.
  • Add accessibility code to QML elements. Accessibility code is basically a locator which will help Selenium identify that element and interact with it.
  • Get elements by its locator. Once we are done with the previous step, we can now access those elements.
  • Perform events on the elements. Once we are able to access elements, we can write code to interact with them.

You can follow this guide to setup Selenium AT-SPI and start writing basic tests. You can also check out this blog post for an in-depth overview.

Figure : Video "Selenium AT-SPI: How Selenium Helps Achieve KDE's Goals" (screenshot from Pradyot Ranjan published under a CC-BY-4.0 license). Introducing Selenium To More KDE Contributors

This project was done under SoK'24 with these deliverables in mind:

  • Improve the setup process of Selenium.
  • Create video guides to introduce Selenium-based GUI testing to more KDE contributors.

I am achieving this by:

  • Enhancing the Selenium setup guide. You can find the updated Setup and Getting Started guides here. It includes all of the latest packages and info about distro-specific packages and dependencies required to setup Selenium. I've also updated the Writing Tests section to account for deprecated function arguments.
  • Creating slides and videos. I have created video presentations for newcomers to Selenium so that it is a smooth transition. For this I'm using KDE's Kdenlive software for video editing. Once the videos are published online, I will update this blog post with links. The videos broadly cover these topics:
  1. An intro video about what Selenium is and how it is useful in achieving KDE's goals.

  2. Setting up Selenium.

  3. Using the accerciser utility to discover accessibility elements.

  4. Writing accessibility code and tests to show how to access elements.

Figure : Using Kdenlive to edit the Selenium videos (screenshot from Pradyot Ranjan published under a CC-BY-4.0 license). Challenges Faced And Looking Forward

Some challenges that I faced were:

  • Updating the setup guide so it is relevant with the latest changes. Selenium-AT-SPI is a moving target with a lot of internal changes and developements. Tracking down distro specific packages and making a list of deprecated/missing dependencies was time-consuming. The latest version of the setup guide can be found here.
  • Making videos for using Selenium. With no prior experience, this was a challenge for me. I am proud to have done it!

As we move ahead, we have some plans for this project. Some of them are:

  • We will be creating support rooms in Matrix to provide further support for KDE developers.
  • We will use Selenium to adapt usage scenario scripts originally written with xdotool so we can compare the energy profiles of the emulation tools themselves.
Interested In Contributing?

If you are interested in contributing to Selenium-AT-SPI, you can join the Matrix channels KDE Energy Efficiency and Automation & Systematization Goal and introduce yourself. Selenium-AT-SPI is hosted here. Thank you to Emmanuel, Rishi, Nitin, and Joseph as well as the whole KDE e.V. and the wonderful KDE community for supporting this project and for all the help along the way. You can also reach out to me via email or on Matrix: @pradyotranjan:gitter.im.

Categories: FLOSS Project Planets

KDE Gear 24.02.2

Planet KDE - Wed, 2024-04-10 20:00

Over 180 individual programs plus dozens of programmer libraries and feature plugins are released simultaneously as part of KDE Gear.

Today they all get new bugfix source releases with updated translations, including:

  • kcachegrind: Fix crash when opening history menu (Commit, fixes bug #483973)
  • gwenview: No longer inhibit suspend when viewing an image (Commit, fixes bug #481481)
  • elisa: Fix broken volume slider with Qt Multimedia backend (Commit, fixes bug #392501)

Distro and app store packagers should update their application packages.

Categories: FLOSS Project Planets

Spyder IDE: Spyder 6 will get a new installer for all platforms and a standalone application for Linux!

Planet Python - Wed, 2024-04-10 20:00

For the last several years, Spyder has offered standalone installers for Windows and macOS which isolate Spyder's runtime environment from users' development environments. This provides a more stable user experience than traditional conda or pip installation methods. However, these standalone installers did not allow implementing desirable features, such as automatic incremental updates or installing external Spyder plugins like Spyder-Notebook and Spyder-Unittest. Additionally, these standalone applications were limited to Windows and macOS.

Our new installers will provide a more consistent experience for users across all platforms, including Linux, while maintaining the benefits of an isolated runtime environment for Spyder. Additionally, they are fully compatible with incremental updates and external plugin management. Look for future announcements about these and other features!

So, what will you see with these new installers? If you are a Windows user, you will continue to have a graphical interface guiding you through the installation process, and will likely not notice any difference from the previous experience.

If you are a macOS user, you will now have a .pkg package installer instead of a .dmg disk image. Rather than drag-and-drop the application to the Applications folder, the .pkg installer provides a graphical interface that will guide you through the installation process with more flexibility.

If you are a Linux user, you will have an interactive shell script guiding you through the installation process. This ensures it is compatible with as many distributions and desktop environments as possible.

In all cases, you will not need to have Anaconda installed, nor do you need an existing Python environment; in fact, you don't even need a preexisting Python installation! These installers are completely self-contained. Spyder will continue to include popular packages such as NumPy, SciPy, Pandas and Matplotlib so you can start coding out-of-the-box. However, you will still be able to use Spyder with your existing conda, venv, Python.org, and other Python installers and environments as before. Furthermore, only Spyder and its critical dependencies will be updated on each new release, which will make getting the latest version a lean and frictionless process.

The Spyder team is really excited about these new installers and the new features they will make possible, and we hope you enjoy them too!

Categories: FLOSS Project Planets

Horizontal Digital Blog: Improving the authoring experience and editorial workflow with ECA

Planet Drupal - Wed, 2024-04-10 16:30
I recently was presented with a relatively simple problem, and decided to explore ECA as a possible solution. The initial problem was a pretty simple use case, and could have been accomplished with a bit of custom code. With the move of this blog to Drupal, we built a simple editorial workflow to give our marketing team some guardrails and control over the publishing process. Since the launch, we've decided to expand this workflow from Draft -> Review -> Published, to include a new state - "Technical Review".
Categories: FLOSS Project Planets

FSF Blogs: Meet the locals: Come to LibrePlanet and connect with free software supporters in New England

GNU Planet! - Wed, 2024-04-10 14:11
New England free software supporters: we invite you to come socialize with other local free software supporters at LibrePlanet 2024.
Categories: FLOSS Project Planets