The extracted release notes trigger a sphinx warning
/tmp/tmp.V6RGP92nc2/src/index.rst:6:Document may not end with a transition.
which we don't seem to get on the full CHANGELOG.rst.
Let's work around that for now.
I'd like to move to a process where everything goes into master first,
and then flows downstream to any release branches (i.e. no merging
of Integration_* branches back into master).
The only thing we need to change for that is to add release notes for
patch releases eagerly on master. That implies that we want to use
the actual version instead of ???. (Only if something goes wrong
in the release process, we need to change this on both branches,
but that should happen too often.)
Given
bind up "echo user up, new notation"
bind \e\[A "echo user up, legacy notation"
prior to b9d9e7edc6 (Match bindings with explicit shift
first, 2025-05-24), we prioritized the legacy notation because
input_mapping_insert_sorted() makes us try longer sequences first --
and "up" is only one key compared to the three-key legacy sequence.
This prioritization was broken in b9d9e7edc6, causing plugins that
update to the "bind up" notation to break users who haven't (#11803).
Even worse, it caused preset bindings to shadow user ones:
bind --preset up "echo preset up, new notation"
bind \e\[A "echo user up, legacy notation"
Restore backwards compatibility by treating matches against legacy
notation like exact matches again.
The only install directory that's not supported is
-DCMAKE_INSTALL_PREFIX=$CARGO_MANIFEST_DIR, but that's a bad idea
anyway since share/ is Git-tracked.
On a system where _CS_PATH is not defined (tested by removing that
code path), we get:
$ cargo b && env -u PATH HOME=$PWD target/debug/fish -c 'set -S PATH'
$PATH[1]: |.local//bin|
$PATH[2]: |/usr/bin|
$PATH[3]: |/bin|
The relative $PATH[1] makes no sense; probably it's an
accident. Restore the traditional $PATH[1]=/usr/local/bin.
Commit bf65b9e3a7 (Change `gettext` paths to be relocatable (#11195),
2025-03-30) made the locale directory (/usr/local/share/locale)
relocatable as well, so that "mv /usr/local /usr/local2" would not
break translations.
But this introduces a weird circular dependency, which was probably
the reason why the locale directory hadn't been relocatable:
1. option parsing might fail and print error messages, which should
be localized, hence require detection of config paths
2. detection of config paths calls `FLOG`, which depends on options
parsing (e.g. "-d config -o /tmp/log")
Since commit bf65b9e3a7, fish initializes the config paths
lazily, as soon as needed by translations.
When initializing config paths, we produce logs. The logs are off by
default so its' fine in practical cases, but technically we should only
log things after we have handled things like FISH_DEBUG_OUTPUT.
Here's an example where the config directory initialization sneakily
injected by an error message's "wgettext_fmt!" causes logs to be
printed to the wrong file spuriously:
$ FISH_DEBUG='*' FISH_DEBUG_OUTPUT=/tmp/log build/fish --unknown-arg
config: exec_path: "./build/fish", argv[0]: "./build/fish"
config: paths.sysconf: ./etc
config: paths.bin: ./build
config: paths.data: ./share
config: paths.doc: ./user_doc/html
config: paths.locale: ./share/locale
fish: --unknown-arg: unknown option
Now we could handle "-d config", "-o", and FISH_DEBUG later, but
that would mean that in this example we don't get any logs at all,
which doesn't seem correct either.
Break the circular dependency by determining config paths earlier,
while making sure to log the config path locations only after parsing
options, because options might affect whether we want to log the
"config" category.
The global variable is only needed for locale, so use explicit argument
passing for everything else, as before.
While at it, make other binaries (fish_key_reader, fish_indent) use
the same localization logic as fish. This means that we need to tweak
the «ends_with("bin/fish")» check.
Closes#11785
This makes no sense:
$ target/debug/fish -d config
config: paths.doc: .local/share/doc/fish
so remove it.
While at it, group config paths by whether they can be embedded.
Rather than having every single config path be an Option<Path>,
clarify that we define either all or nothing.
If we want to decide this at runtime, we'd use an enum; but it's all
known at compile time, so we can give the reader even more information.
Unfortunately this means that compile errors in non-embed-data
code paths might go unnoticed for a while, and rust-analyzer often
doesn't work in those code paths. But that's a general problem with
the compile-time feature, it seems orthodox to ifdef away as much
as possible.
There are some odd data paths that don't follow the "all or nothing",
the next commits will fix this.
Note that this breaks localization for target/debug/fish built with
embed-data. But as soon as fish was moved out of the repo, that was
already broken.
Commit 3dc49d9d93 (Allow installable builds to be installed into a
specific path (#10923), 2024-12-22) added some ifdefs to use installed
config paths for installable builds that have already been installed.
The "installable" feature has been superseded by "embed-data"
which no longer uses config paths to retrieve files,
so remove those code paths. Further cleanup to follow.
Assuming every in-tree build uses CMake, the source tree must
also be a valid build directory, so we already return in the
env!("FISH_BUILD_DIR") code path above.
Commit 8b102f2571 (Stop using Cargo's OUT_DIR,
2025-06-22) accidentally removed canonicalization of
FISH_BUILD_DIR=${CMAKE_BINARY_DIR}. This means that if the path to
${CMAKE_BINARY_DIR} includes a symlink, ${CMAKE_BINARY_DIR}/fish will
wrongly use /usr/share/fish instead of ${CARGO_MANIFEST_DIR}/share.
Fix this and reintroduce the comment.
That configuration is already tested, but not clippy-checked yet.
This sometimes causes things like unused imports linger on master.
Let's at least enable clippy for stable Rust.
Also do the same build_tools/check.sh; since that script already runs
"cargo test --no-default-features", this shouldn't add much work,
though I didn't check that.
We do not need timestamps of embedded files, so setting them to 0
reduces the potential for unwanted changes to the binary, allowing for
better build reproducibility.
Also check that "cd fish-site && make && make new-release" doesn't
leave behind untracked files we're not aware of. This implies that
this script ought to refuse to run if there are untracked files,
at least in fish-site.
Things that are not currently happening in this workflow:
- No GPG-signature on the Git tag
- No *.asc signature file for the tarball (or for any other release assets)
- No GPG-signed Debian and other OBS packages
To-do:
- remove the corresponding entries from
https://github.com/fish-shell/fish-shell/wiki/Release-checklist
and link to this workflow.
- Maybe add some testing (for the Linux packages)?.
- Let's hope that this doesn't cause security issues.
Usage:
1. run "build_tools/release.sh $version"; this will create and push
a tag, which kicks off .github/workflows/release.yml
2. wait for the draft release to be created at
https://github.com/fish-shell/fish-shell/releases/tags/$version
3. publish the draft (manually, for now). This should unblock the
last part of the workflow (website updates).
Closes#10449
Incremental usage example:
version=4.0.3
repository_owner=fish-shell
remote=origin
cd ../fish-shell-secondary-worktree
git tag -d $version ||:
git push $remote :$version ||:
git reset --hard origin/Integration_$version
for d in .github build_tools; do {
rm -rf $d
cp -r ../fish-shell/$d .
git add $d
} done
git commit -m 'Backport CI/CD'
echo "See https://github.com/$repository_owner/fish-shell/actions"
echo "See the draft release at https://github.com/$repository_owner/fish-shell/releases/$version"
../fish-shell/build_tools/release.sh $version $repository_owner $remote