This document details how the we use GitHub at Ably. The goal is to conform, where possible, so that as developers move from repository to repository the experience is predictable and unsurprising.
The standards and best practices documented on this page are intended to be:
On first inspection, for those granted access to Ably’s internal systems, it can be a little bit confusing that we have two ticket / issue management systems in concurrent use for our client libraries (GitHub issues and Jira). They complement each other and this section aims to explain why.
One of our key company values is being open for all. Our client library codebases align with this value as they are open source, available to view in every detail in the public domain.
Allows external parties to contribute by:
Allows us to:
Used for internal management.
GitHub issues are bidirectionally synchronised with Jira.
Jira allows us to add internal meta-information beyond what GitHub issues allow us to - this includes:
Generally the following operations should be performed from GitHub, not Jira (unless they are issues which solely exist in Jira):
The primary reason is that this uses your real GitHub identity to associate with the operation from a public domain perspective. Operations done from Jira sync over to GitHub using a bot account and that looks ugly and awkward for external viewers.
The convention at Ably is to name repositories in the ably
GitHub org that contain the source code for a client library / SDK with an ably-
prefix.
For example, ably/ably-js
, where ably
is the org and ably-js
is the repository name.
See Pull Requests for guidance around how we work on PRs in open source.
This section describes our ways of working with GitHub workflows.
GitHub documents them under the umbrella of GitHub Actions, which has resulted in ‘Actions’ somewhat incorrectly being adopted as the all-encompassing title for this technology.
The reality is that an Action is just a component of this technology stack, a thing that is downloaded and invoked by workflows (see jobs.<job_id>.steps[*].uses
in the syntax for workflows).
This is the name of the file within the .github/workflows
folder.
yaml
extensionassemble
:
./gradlew assemble
sdk.ably.com
(staging)check
- for basic, quick verification tasks, including:
./gradlew check
docs
:
sdk.ably.com
(staging)emulate
:
./gradlew connectedCheck
integration-test
:
-
)integration-test-
publish
:
report
:
The root name
key, typically defined at the top of the workflow file, should match the file name with:
': '
)Examples:
Check
for check.yaml
Integration Test
for integration-test.yaml
"Integration Test: Node"
for integration-test-node.yaml
(double quotes needed in this case for YAML to specify a string definition)The name
key, at the top of the workflow file, is defined as optional.
When we started using workflows, we took the decision to take advantage of this optionality and not define the root name
for workflow files, due to the fact that it generally seemed to just repeat the name of the file.
More recently, we’ve come to realise that the GitHub user interface will use this name to represent workflows in a much more concise and human readable form.
When omitted, the full path to the workflow is used and this is ugly (for example: as .github/workflows/check.yaml
in the ‘Actions’ tab of a repository).
on:
)Unless there a good reason to deviate from this, workflows should always be configured to trigger as follows:
on:
workflow_dispatch:
pull_request:
push:
branches:
- main
This one’s a work in progress at the moment.
If in doubt use check
.
We’re also using build
in some places (e.g. Android Asset Tracking’s docs workflow), where the job’s purpose is generating built output that’s intended to be accessible beyond the lifespan of the workflow.
It’s important because when we create branch protection rules (typically for the default branch, main
) we want to tick the box to “Require status checks to pass before merging”, which then presents us a list of job names under “Status checks found in the last week for this repository”.
By default GitHub’s fail-fast property on strategies is set to true
.
While that might be kinder from GitHub’s perspective on their server resources, as jobs will get cancelled prematurely, it doesn’t help us debug when things go wrong.
So, generally, our preference is to override the default and explicitly specify false
for fail-fast
.
It’s a growing trend across our org. :smiling_imp:
To support our workflows we’re developing our own Actions - the LEGO-like modules that allow us to build build ourselves bigger structures from proven components of functionality.
Pushing artifacts to sdk.ably.com (see this internal page for more information on the S3 bucket that underlies this domain).
The docs repository has been using these for a while, with its own naming convention for environments.
We are also evolving a naming convention for environments. Initially modelled in ably-flutter #92, tied in with the SDK Upload Action.
The following table canonically defines labels we use in common across our open source repositories:
Name | Color | Description | Additional Notes |
---|---|---|---|
blocked-by-ably |
We can’t proceed until something under our direct control, in a different codebase, happens. | Comments should be added to indicate what the blockage is (e.g. another repository). | |
blocked-by-external |
We can’t proceed until something outside of Ably’s direct control happens. | Comments should be added to indicate what the blockage is. | |
breaking |
Backwards incompatible changes made to the public API. | Implies a need to release related changes in a major version bump. |
|
bug |
Something isn’t working. It’s clear that this does need to be fixed. | Usually implies that related changes can be released in a patch version bump. |
|
build |
Relates to the tooling used to build or release the contents of this repository. | ||
code-quality |
Affects the developer experience when working in our codebase. | Relating to the maintainabily of the codebase, not affecting the public API, therefore unlikely to be customer facing. | |
documentation |
Improvements or additions to public interface documentation (API reference or readme). | ||
enhancement |
New feature or improved functionality. | Implies a need to release related changes in a minor version bump. |
|
example-app |
Relates to the example apps included in this repository. | Not all repositories have embedded example apps. | |
failing-test |
Where an automated test is failing either locally or in CI. Perhaps flakey, wrong or bug. | ||
investigate |
Requires further investigation to decide the most appropriate label(s). | ||
testing |
Includes all kinds of automated tests, the way that we run them and the infrastructure around them. |
The Name, Color and Description values above should be used when creating the corresponding labels in repositories.
It is expected that some labels will be used together - for example enhancement
and breaking
, indicating a feature that’s been added in a way that introduces backwards incompatible changes into the public API, therefore implying the need to release in a major
(not minor
) version bump.
The breaking
and enhancement
labels must be applied to all pull requests to which they apply (see: Guidance on Releases: Version Bump).
They can also be applied to linked issues, but this is less important than labelling the change itself (i.e. the pull request).
While GitHub does allow us to use mixed case and spaces in label names, we’ve restricted ourselves to all lowercase and dashes instead of spaces to separate words.
We do not have any labels that imply or otherwise infer importance or prioritisation of issues or pull requests because that information is internally managed using Jira (see GitHub First).
Things that the Ably Engineering Team, in the open source work that we facilitate, intentionally don’t require contributors to do:
So, why do we leave some things flexible and up to individual preference?
Primarily, as stated at the start of this page, we - as a team - learn from experience. This means that there are things we end up converging on, as best practices or standards, because they’ve been shown to be sensible things to do in order to enable our work to progress productively and predictably for everybody involved. We, therefore, feel it’s worthwhile sharing those things as standards and best practices on this page.
However, conversely, there are things that - again, based on our experience - haven’t been shown to matter that much. More often, it turns out that many of these things are somewhat subjective in nature. We don’t feel it’s necessary to mandate rules or policies around these things as, on balance, we would prefer to tip the balance in these areas to allow individuals to express themselves with the work that they do in the way that they feel most comfortable.
We’re not machines. We’re humans. Let’s keep this fun!