Maintenance
To keep SSVP clean, we have several standards for how the project should be maintained.
Pull Requests
PRs should be continually commented on until they are eventually rejected or merged.
Merge Types
Under no circumstances, except when absolutely required (major conflics), should merge commits be used. In most cases, a resolution commit and a squash can serve the purpose of a merge commit.
Generally, commits should be applied with a rebase. Rebasing isn’t perfect, but it does perform a lot better for most purposes than merge commits, and keeps authorship.
If there are a lot of commits, then a squash commit may be necessary. This is more acceptable with single ownership of the commits; however, it is more preferred for users to pre-squash. Whenever a squash commit is required, it’s important to add Co-developed-by for every author.
Tagging
Tagging a release is a great occasion, but there’s several things to keep in mind:
Anything with the version number needs to be updated. This should be done in a single commit (this is a great time for a squash commit if necessary). It should be the last commit before tagging.
Testing releases: - Level 0 releases must be deeply, deeply tested. - Level 1 releases should be thoroughly tested. - Level 2 releases should have basic testing done.
Running: a live instance demonstrating the new version must exist; this will usually be status.amyip.net.
Ensure that everything’s been linted, reformatted, etc.
Verify documentation is up-to-date - both in terms of instructions, and in terms of Sphinx’s version number (this is something that’s not always covered)
Packaging
When packaging, local changes to release-info.json
should be made, removing the +
and adding any appropriate suffixes.
For instance, for in-progress v0.3.0
, the release version is set as 0.3.0+
. When packaging, this should be changed
to 0.3.0
. The commit after the tag would then change the release version to 0.4.0+
.
RPMs
Building should only be done on a clean system. Make sure you don’t have an SSVP config file, or anything else; you risk leaking secrets.
First, make sure you have the necessary dependencies installed:
dnf install -y make jq nodejs nodejs-npm rpmdevtools rpmlint
Then, just run:
make rpm
The RPM will be generated at rpmbuild/RPMS
.
Enterprise Linux RPMs
There is a known issue when building RPMs or using
install.sh
on Enterprise Linux distributions (Rocky, RHEL, Alma, CentOS, Oracle).
Detection
You can tell if your distribution is Enterprise Linux by running the following command on a known-installed
package (bash
used as an example):
dnf list bash
and then looking at the last component of the second column. If the system is Enterprise Linux, it will
be of the format elN
, where N is some number. If it does not contain el
, then it is not
Enterprise Linux, and this is not the bug source.
Fixing
The fix depends on whether you are using install.sh
or using the RPM; if the former, apply the
following edits to srv/autoinstall-deps-system.sh
, if the latter, to ssvp.spec.fmt
.
nodejs-npm
changed tonpm
You also need to install python3-pip
, and then run:
pip3 install pyopenssl gunicorn Flask mysql-connector-python
If you are building an RPM, you must remove those packages from ssvp.spec.fmt
.
SUSE
The development package installation list is slightly different:
zypper install make nodejs npm rpm-build rpmdevtools rpmlint jq
You can then build and install the RPM as normal. Two things will come up:
You’ll be asked about python3-flask. You should just choose to ignore the issue. You then later need to run:
zypper install python3-pip pip3 install Flask
After that, it’ll throw up a warning about the RPM being unsigned. This is fully safe to ignore.
Linting
It is good to lint whenever you’re going to commit; however, it is understood that this can be tedious. As such, contributors are given discretion on whether to lint. Most small issues will be caught when preparing for release, so lint checking is not critical; further, because of the many linting things that can come up that are unimportant to SSVP, we do not run linters in CI. It is absolutely imperative to lint, however, when preparing for a release.
Linting depends on the language, and should be run on every modified file (and, for releases, every file).
Python
First, ensure that pylint
is installed:
pip3 install pylint
Then, for every file you need to lint, run:
pylint <filename>
All warnings should be treated as optional; however, we have advice on the following warnings:
C0303/trailing-whitespace: if your editor can fix this, it’s welcome, but it’s not critical. This commonly occurs in GPL notices.
C0301/line-too-long: please separate into lines if reasonable If not, however, that is completely fine - sometimes code readability suffers when trying to comply.
Docstring objections: C0114 and C0116 can be safely ignored. We do not use docstrings.
R1732/W1514: tread carefully. Passage into reasonably-handled functions, such as
json
functions, is acceptable (usage of directly passed open). However, if the file pointer is being used directly, then with should be used. Unspecified encodings are generally fine, with few exceptions; these exceptions cause bugs and would appear elsewhere, so relying on the linter is unnecessary.C0123/unidiomatic-typecheck: these can be optionally modified, but it is not necessary. Using type is perfectly fine, and isinstance should only be used if the switch is trivial.
C0411 and other import objections: these should be fixed within another commit, but are not critical; don’t bother fixing them in their own commit.
Rust
First, format the code:
cargo fmt
Then, use Rust Analyzer to lint the code. This can often be done directly in your IDE.
TypeScript
Just run:
eslint js/*