Get Ready for the New RBCommons

Update: We’re postponing just a bit longer while we work through a last-minute bug. We’ll announce the new date soon!

We’re excited to announce that RBCommons will be getting a major update with tons of new features and more flexible pricing for teams of all sizes.

We want to show off what’s coming soon. There’s a lot!

Commit Histories

Previously, any code changes posted to RBCommons would show up as a squashed diff, merely showing the difference between the upstream code and the tip of your local branch. If your change was built with multiple commits, there was really no way to really dive into them individually. Until now.

When using Git, or Mercurial, or other DVCS solutions, RBTools will upload the complete commit history of your branch. You can look at the diff of the entire branch as a whole just as before, but also dig down into each individual commit, or even ranges of commits.

The New Unified Draft Banner

Until now, your draft review requests, reviews, and replies were all managed separately, each with their own green draft banner. While it was obvious when there was a draft review request update or a draft review, sometimes draft replies could get lost in long threads.

We’ve rebuilt this with a new unified banner that always sits at the top of the page, collecting all your work together in one place. You’ll never lose a draft again.

The new Unified Review Banner, showing that there are changes, a review, and a reply ready to publish. Alongside that is a Publish button and a Review menu. Under that is a textbox saying "Describe your changes."

With the new banner, you can now publish all your drafts at once, generating a single e-mail. This means you can publish all of your replies to people’s reviews along with the updated version of your change with a single click. Fun fact, this was one of our most-requested features ever.

You can also add comments to your own diff before you publish it, which is handy for calling out parts of the diff to jump-start the conversation.

Dark Mode

There’s nothing worse than staying up late to review code and feeling blinded by your screen. With dark mode, you can reduce eye strain and work comfortably no matter the time of day.

A review request shown in dark mode, with a dark cool-blue color palette.

Markdown Formatting Toolbar

Rich text editors throughout the product now include a new toolbar for common Markdown formatting options. Don’t remember how to make something italic or include a link? Just click a button!

A text field with the Markdown formatting toolbar below it, showing the following buttons: Bold, Italic, Strikethrough, Code Block, Link, Upload Picture, Bullet List, Numeric List.

An Improved Dashboard

The “Overview” section

The new Overview section of the Dashboard is a combined view that shows both your incoming and outgoing review requests. This is your new default view whenever you open the Dashboard.

Stale Ship Its!

The Ship It! indicator in the dashboard will now show as greyed out if there has been an update to the review request since the Ship It! was given.

If you don’t have this column added, click the pencil to the right of the columns and add it (or any other column you like!). Click and drag columns to place them in any order you prefer.

The Dashboard, with stale Ship It indicators shown in grey instead of green.

All Sorts of Diff Viewer Features

Trojan Character Detection

Trojan Source attacks employ special Unicode characters, such as bi-directional control characters, zero-width spaces, or confusable/homoglyph characters (which have the appearance of other common characters) to trick reviewers into approving possibly malicious code.

These are CVE-2021-42574 and CVE-2021-42694, and affect many tools on the market (code review tools, IDEs, repository browsers, and more).

Review Board now detects characters that can be used in these attacks, and flags them in the diff viewer. When found, a helpful notice with examples and informative links will be shown at the top of the file, and the lines themselves will be flagged.

The Unicode characters will be highlighted and replaced with the Unicode codepoint, rendering the attack harmless. Reviewers can click a button to see how the code would have looked.

A warning block shown on a diff containing malicious trojan code. The warning explains the kind of attack, warns the user to review carefully, and provides a button for toggling the hidden malicious characters.

Current File Display and Quick Switch

When browsing through the diff, the list of files will now dock into the banner at the top of the screen. This will always show you the names of the files that are visible on the screen, so you always know what you’re looking at.

Clicking the menu at the side of this file list will pop open the full list, so you can quickly navigate to other files without having to scroll all the way back up to the top of the page.

The diff viewer showing the current file docked to the top of the page, with a menu for navigating to other files.

Binary Files in Diffs

Review Board now supports displaying, reviewing, and diffing certain types of binary files included as part of your code diffs.

At the moment this is limited to image files, but support for additional file types (including PDFs) are in the works.

This requires posting your changes with RBTools 5.0+, and is supported for a limited set of version control systems:

  • Git
  • Mercurial
  • Perforce
  • Subversion
An image diff in the diff viewer, showing a split view between two versions of a game character.##

Mobile Diff Viewer

The diff viewer has been updated with a new responsive mode when viewing on mobile devices. This will change the display from the two-column view into a single column for content. This makes it much easier to read and interact with diffs on phones and other mobile devices.

The diff viewer in mobile mode, showing inserted code, deleted code, and moved code, with comments filed.

New Integrations

RBCommons is adding new chat integrations with Discord, Matrix, and Microsoft Teams, as well as a new CI integration with Jenkins.

New Flexible Pricing

Finally, we’d like to announce that we’re going to be changing the pricing for RBCommons.

Our new pricing model has two tiers, Basic and Business. Both of these are priced per-user, so you don’t have to worry about a big price jump just because you need to add a 26th user.

All existing team accounts will continue to be grandfathered in on their current plan, so you don’t have to switch to the new plans unless you want to. If and when you’re ready, simply change your plan to take advantage of the new flexible pricing.

Plus…

There are many additional tweaks and polish that you’ll see, including:

  • Draft indicators for file attachments that tell you whether an attachment is new, pending deletion, or has a new update within your current draft.
  • Quick options to archive after publishing, and click the archive icon itself to toggle the archive state instead of having to wait for a drop-down menu to appear.
  • We’ve been tweaking colors and spacing, and polishing down some rough edges to improve the look and feel, especially for reading diffs.
  • Better support for mobile devices.
  • Better accessibility support for screen readers, keyboard navigation, low contrast, and other accessibility tools.
  • Renamed “submitted” to “completed” for review request states. The word “submitted” throughout the Review Board UI was a holdover from the very earliest days of the tool, when we adopted the Perforce naming convention for when changes were pushed to a central repository. This has long been a source of confusion, so we’ve renamed this state to “completed”.
  • Clicking a text field on a review request now positions the cursor where you click.
  • Too many bug fixes to count.

Coming Soon

We’re in the final stages of testing and building out new servers. We expect to announce a release date soon, and will include it in the announcement banner at the top of RBCommons.

For further updates on RBCommons and all things Review Board, you can follow us on:

Or join us on the new Review Board Discord.

Read More

A Sneak Peak Into the New RBCommons

Our team’s been hard at work bringing RBCommons to the cutting-edge Review Board 7 platform. This is a massive update with tons of new features, and we think it’s time to give you a glimpse of what’s coming:

Multi-commit review requests for Git and Mercurial

In the past decade, DVCS has become the norm, and many people work in local branches with lots of individual commits. Previously, any code changes posted to RBCommons would show up as a squashed diff, merely showing the difference between the upstream code and the tip of the local branch.

When using DVCS systems like Git or Mercurial, RBTools will now upload the commit history of your branch. You can look at the diff of the branch as a whole, but also dig down into each individual commit.

A list of commits for a review request, with summaries for each and selectors for choosing a range to view.

An improved review experience

Until now, your draft review requests, reviews, and replies were all managed separately, each with their own green draft banner. While it was obvious when there was a draft review request update or a draft review, sometimes draft replies could get lost in long threads.

The new unified banner always sits at the top of the page, and collects all your work together in one place. You can also use this to publish all your drafts at once with a single click and a single-email notification.

The new review banner, showing pending changes, one review, and one reply. A button saying "Publish All" to the right of that summary publishes all pending drafts. A "Review" drop-down to the right of the button controls the review. A "Describe your changes" field sits below it.

Dark mode

There’s nothing worse than staying up late to review code and feeling blinded by your screen. With dark mode, you can reduce eye strain and work comfortably no matter the time of day.

A typical review request, but shown in dark mode, with a dark cool-blue color palette.

And just so much more

There’s a lot more coming, but we wanted to keep this first message short. We’re working hard to make this transition as seamless as possible for you. Keep an eye out for more details about all the new features and a timeline for the rollout.

If you have any questions, please feel free to reply to this e-mail.

Thanks for using RBCommons! We’re excited to bring Review Board 7 to you.

Read More

beanbag-docutils 2.2: Enhanced JSON Output

beanbag-docutils is our collection of extensions for the Sphinx documentation platform.

This is a major feature release that introduces some new capabilities for JSON output, making it easier to integrate documentation into your own sites:

  • The metadata extension extracts .. meta:: into the JSON output for a page.
  • The json_writer extension replaces the sphinxcontrib-serializinghtml JSON writer and includes both a copy of the docs-wide Table of Contents structure in the globalcontext.fjson file and per-page anchor navigation HTML in the page’s .fjson file.

You can see how we make use of these new capabilities in the brand-new Review Board documentation site.

Installation

$ pip3 install beanbag-docutils==2.2

Learn More

Read More

Djblets 3.1: Token Deprecations and API Fixes

We’ve released Djblets 3.1, our collection of production-quality add-ons for Django.

This release features:

  • Ability to deprecate token generators
  • Deprecated token information in the API
  • Fixes for URI template name collisions in the API
  • Fixes for generating the new API tokens introduced in Djblets 3
  • Python 3 type hints for the djblets.registries, djblets.secrets, and djblets.siteconfig models

For complete details, see the release notes.

Read More

Django Evolution 2.2: Django 3.2-4.1 Support

Django Evolution 2.2 is a major feature release, offering new database features, improved compatibility, and several bug fixes.

Django Evolution is our alternative database migration library for Django, which supports a wide range of Django versions and optimized application of database changes. It targets self-managed applications, like Review Board, which may potentially go several releases between upgrades.

The highlights include:

  • Compatibility with Django 1.6 through 4.1, and Python 2.7 through 3.11
  • Support for conditions, expressions, opclasses, and field lists in Django’s Index classes.
  • Ability to change field types in ChangeField.
  • Improved settings for defining project-provided custom evolutions.
  • Bug fixes for MySQL compatibility, edge cases in SQL generation for indexes, and Python 3.10 compatibility.

The release notes cover the full list of changes in Django Evolution 2.2.

Read More

RBTools 3.1.2, Power Pack 5.1.1

Today, we’re bringing two new releases of RBTools and Power Pack, focusing on stability and feature improvements.

RBTools 3.1.2 Highlights

  • Now supports the upcoming Python 3.11.
  • Added back directory change information to diffs for ClearCase and VersionVault, and fixed problems posting symlinks.
  • Fixed several issues generating Perforce diffs, especially on Python 3.
  • Fixed applied patches on Subversion.

To learn more about this release, see the RBTools 3.1.2 release notes.

Power Pack 5.1.1 Highlights

  • Added support for showing changes to directories when using ClearCase or VersionVault
  • Fixed broken repository configuration forms when selecting Cliosoft SOS on Review Board 4.0.3 or older.

This upgrade is available for all existing Power Pack users.

To learn more about this release, see the Power Pack 5.1.1 release notes.

Read More

Djblets 2.3: Preparing for the Future

Djblets 2.3 is now out. This release adds compatibility fixes for Python 3.10 and gets our code ready to move to newer dependencies.

Highlights include:

  • Python 3.10 compatibility shims for Django 1.11.
  • Modern Django middleware support for extensions.
  • Babel 7.x for building extension static media files.
  • Full compatibility with Python-Markdown 2.x.
  • Support for caching data in cache_memoize() without needing to wrap in a list or string.

We’re getting 3.x ready for release. This will move the codebase to require Python 3.7+ and Django 3.2 LTS, finally bringing support for modern codebases.

See the release notes for the full list of changes.

Read More

Django Evolution 2.1.3: Evolution and compatibility fixes

Django Evolution 2.1.3 a small but important bug fix release that addresses issues with Python 3.10, mysqlclient, and evolving very old databases.

Compatibility Fixes

Python 3.10 removed some deprecated imports from collections, which Django 2.0 and older depend on. When using this combination of versions, Django Evolution will bring back those legacy imports, allowing Django to work again.

mysqlclient also received a similar fix. Django 1.11 and older depended on some unintentional functionality, which mysqlclient maintained until the 2.1 release. We now patch these versions of Django at runtime to continue working.

Upgrade Fixes

Two important issues affecting upgrades were addressed:

  1. Django Evolution no longer tries to apply evolutions to models that were just introduced. This was a regression from previous releases.
  2. When upgrading from very old databases, some state for a model’s unique_together index couldn’t be compared properly, causing issues applying some upgrades. The old format for this state is now taken into account during comparison.

Coming Up…

We’re preparing Django Evolution 2.2, which will support all versions of Django up through 4.0. This should be coming soon.

In the meantime, check out the release notes for the full changes, including other fixes in this release.

Read More

kgb 7.0: Pytest, Python 3.10, and more

kgb 7.0 has been released with a handful of new features:

  • Python 3.10 support
  • Support for pytest, and other non-unittest-based test frameworks
  • Snake-case and standalone assertion methods
  • Workarounds for spying on methods with poorly-implemented decorators

It also drops official support for Python 2.6 and 3.4-3.5 (though these should still work for now, if you need them).

pytest

kgb now provides a spy_agency fixture for pytest unit tests. This will set up a SpyAgency for you, letting you spy on functions and assert calls. For example:

def test_doomsday_device(spy_agency):
    device = DoomsdayDevice()
    spy_agency.spy_on(device.destroy_reality, call_original=False)

    device.trigger_the_event()

    spy_agency.assert_spy_called(device.destroy_reality)

The SpyAgency will be managed for the lifetime of the test, removing spies upon completion.

Snake-case and standalone assertion methods

We’ve provided snake_case versions of all the assertion methods, making for more natural tests. For instance, you can use assert_spy_called_with() instead of assertSpyCalledWith(). The old camelCase versions will continue to exist, though.

You can also call assertion methods without needing to mix in a SpyAgency into your test. Just import from kgb.asserts. This is useful if you have a need to spy on methods and assert them within non-unit test code, or without access to a SpyAgency. For example:

from kgb.asserts import assert_spy_called_with

def check_connection_state(api_connection):
    assert_spy_called_with(api_connection.make_request,
                           url='https://middleman.zyx',
                           method='POST')

Workarounds for bad decorators

Before, if you were trying to spy on a method (particularly unbound methods) wrapped in a decorator, and that decorator didn’t preserve the function’s original name, you’d hit an error looking up the method.

You can now work around this by passing the original function name when setting up a spy. For example:

def bad_decorator(func):
    def _wrap(*args, **kwargs):
        return func(*args, **kwargs)

    return _wrap

class BadClass:
    @bad_decorator
    def good_func(self):
        return 42

def test_good_func(spy_agency):
    spy_agency.spy_on(BadClass.good_func,
                      owner=BadClass,
                      func_name='good_func')

kgb will try to detect when you need this and emit a warning during the test.

Get started with kgb 7.0

See the release notes for the full list of changes.

You can install kgb today through pip:

$ pip install -U kgb

Visit our kgb documentation to see how to use kgb in your projects.

Read More

kgb 6.1: New spy operations, with nesting

kgb 6.1 has been released, featuring some new spy operations and enhancements to existing ones.

kgb is our Python unit test library for crafting function spies, making it easy to check on the calls made during a test or to override their behavior, in ways not possible with Python’s mock.

New spy operations

Two new spy operations, kgb.SpyOpReturnInOrder and kgb.SpyOpRaiseInOrder, have been added. These work like a combination of kgb.SpyOpReturn/kgb.SpyOpRaise and kgb.SpyOpMatchInOrder. Each takes a list of results, and each call will receive the next result in the list, making it really easy to build tests that, somewhere, involve repeated calls to some function.

For example:

spy_on(our_agent.get_identity, op=kgb.SpyOpReturnInOrder([
    'nobody...',
    'who?',
    'not telling...',
]))

spy_on(pen.emit_poison, op=kgb.SpyOpRaiseInOrder([
    PoisonEmptyError(),
    Kaboom(),
    MissingPenError(),
]))

Nesting spy operations

The kgb.SpyOpMatchInOrder and kgb.SpyOpMatchAny operations can now nest other spy operations, which simplifies returning or raising values, and can even allow for more advanced interactions with a spy.

The call definitions passed now accept an 'op' key pointing to a spy operation instance, which will be invoked if a call matches.

For example:

spy_on(lockbox.enter_code, op=kgb.SpyOpMatchInOrder([
    {
        'args': (42, 42, 42, 42, 42, 42),
        'op': kgb.SpyOpRaise(Kaboom()),
        'call_original': True,
    },
]))

Get started with 6.1

See the release notes for the full list of changes.

You can install kgb today through pip:

$ pip install -U kgb

Visit our kgb documentation to see how to use kgb in your projects.

Read More