Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 80 additions & 35 deletions .github/workflows/gh-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ on:
tags:
- v*
workflow_dispatch:
inputs:
version:
description: "Release tag to backfill (for example, v0.70.2); leave empty to publish master"
required: false
type: string

env:
RUST_VERSION: 1.93.0
Expand All @@ -19,6 +24,30 @@ jobs:
runs-on: warp-ubuntu-latest-x64-2x # needs at least 100 gb hdd
steps:
- uses: actions/checkout@v6
with:
ref: ${{ inputs.version || github.ref }}

- name: Resolve documentation target
id: docs_target
env:
REQUESTED_VERSION: ${{ inputs.version }}
run: |
if [[ -n "$REQUESTED_VERSION" ]]; then
checked_out_tag="$(git describe --tags --exact-match)"
if [[ "$checked_out_tag" != "$REQUESTED_VERSION" ]]; then
echo "Requested $REQUESTED_VERSION but checked out $checked_out_tag" >&2
exit 1
fi
echo "tag=$REQUESTED_VERSION" >> "$GITHUB_OUTPUT"
elif [[ "$GITHUB_REF" == refs/tags/* ]]; then
echo "tag=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"
elif [[ "$GITHUB_REF" != refs/heads/master ]]; then
echo "Refusing to publish master documentation from $GITHUB_REF" >&2
echo "Select an exact release tag with the version input instead." >&2
exit 1
else
echo "tag=" >> "$GITHUB_OUTPUT"
fi

- uses: Swatinem/rust-cache@v2

Expand All @@ -31,18 +60,40 @@ jobs:
run: cargo install --locked --debug --path ./forc

- name: Install Forc plugins
env:
DOCS_TAG: ${{ steps.docs_target.outputs.tag }}
run: |
cargo uninstall forc-mcp || true
rm -f "${CARGO_HOME:-$HOME/.cargo}/bin/forc-mcp"
cargo install --locked --debug --git https://github.com/FuelLabs/forc forc-client
cargo install --locked --debug --git https://github.com/FuelLabs/forc forc-crypto
cargo install --locked --debug --path ./forc-plugins/forc-debug
cargo install --locked --debug --path ./forc-plugins/forc-fmt
cargo install --locked --debug --path ./forc-plugins/forc-doc
cargo install --locked --debug --path ./forc-plugins/forc-lsp
cargo install --locked --debug --path ./forc-plugins/forc-migrate
cargo install --locked --debug --git https://github.com/FuelLabs/forc forc-node
cargo install --locked --debug --path ./forc-plugins/forc-publish
if [[ -d ./forc-plugins/forc-client ]]; then
# Before the plugin repository split, release tags carried these
# plugins in-tree. Use those exact sources when backfilling docs.
for plugin in forc-client forc-crypto forc-mcp forc-node; do
if [[ -d "./forc-plugins/$plugin" ]]; then
cargo install --locked --debug --path "./forc-plugins/$plugin"
fi
done
elif [[ -z "$DOCS_TAG" ]]; then
# Default-branch documentation follows the current plugin sources.
cargo install --locked --debug --git https://github.com/FuelLabs/forc forc-client
cargo install --locked --debug --git https://github.com/FuelLabs/forc forc-crypto
cargo install --locked --debug --git https://github.com/FuelLabs/forc forc-node
elif [[ "$DOCS_TAG" == v0.71.2 ]]; then
# Post-split plugins release independently. Pin the compatibility
# set recorded for Sway v0.71.2 in FuelLabs/forc releases.toml.
cargo install --locked --debug --git https://github.com/FuelLabs/forc --tag forc-client-0.71.3 forc-client
cargo install --locked --debug --git https://github.com/FuelLabs/forc --tag forc-crypto-0.71.1 forc-crypto
cargo install --locked --debug --git https://github.com/FuelLabs/forc --tag forc-node-0.71.3 forc-node
else
echo "No independent Forc plugin compatibility set is recorded for $DOCS_TAG" >&2
echo "Add exact plugin tags before publishing this release's command reference." >&2
exit 1
fi
for plugin in forc-debug forc-fmt forc-doc forc-lsp forc-migrate forc-publish; do
if [[ -d "./forc-plugins/$plugin" ]]; then
cargo install --locked --debug --path "./forc-plugins/$plugin"
fi
done

- name: Install mdbook-forc-documenter
run: cargo install --locked --debug --path ./scripts/mdbook-forc-documenter
Expand All @@ -67,23 +118,23 @@ jobs:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./sway-lib-std/out/doc
destination_dir: master
if: github.ref == 'refs/heads/master'
if: steps.docs_target.outputs.tag == ''

- name: Deploy master book
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs/book/book
destination_dir: master/book
if: github.ref == 'refs/heads/master'
if: steps.docs_target.outputs.tag == ''

- name: Deploy master reference
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs/reference/book
destination_dir: master/reference
if: github.ref == 'refs/heads/master'
if: steps.docs_target.outputs.tag == ''

- name: Create master book redirect file
run: |
Expand All @@ -94,7 +145,7 @@ jobs:
<meta http-equiv="refresh" content="0; URL=../master/book">
<link rel="canonical" href="../master/book">
EOF
if: github.ref == 'refs/heads/master'
if: steps.docs_target.outputs.tag == ''

- name: Deploy index.html redirect file to master
uses: peaceiris/actions-gh-pages@v4
Expand All @@ -103,67 +154,61 @@ jobs:
publish_dir: ./tmp
destination_dir: ./master
keep_files: true
if: github.ref == 'refs/heads/master'

- name: Get tag
id: branch_name
run: |
echo ::set-output name=BRANCH_NAME::${GITHUB_REF#refs/tags/}
if: startsWith(github.ref, 'refs/tags')
if: steps.docs_target.outputs.tag == ''

- name: Deploy book tag
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs/book/book
destination_dir: ${{ steps.branch_name.outputs.BRANCH_NAME }}/book
if: startsWith(github.ref, 'refs/tags')
destination_dir: ${{ steps.docs_target.outputs.tag }}/book
if: steps.docs_target.outputs.tag != ''

- name: Deploy reference tag
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs/reference/book
destination_dir: ${{ steps.branch_name.outputs.BRANCH_NAME }}/reference
if: startsWith(github.ref, 'refs/tags')
destination_dir: ${{ steps.docs_target.outputs.tag }}/reference
if: steps.docs_target.outputs.tag != ''

- name: Deploy std tag
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./sway-lib-std/out/doc/std
destination_dir: ${{ steps.branch_name.outputs.BRANCH_NAME }}/std
if: startsWith(github.ref, 'refs/tags')
destination_dir: ${{ steps.docs_target.outputs.tag }}/std
if: steps.docs_target.outputs.tag != ''

- name: Create tag book redirect file
run: |
mkdir ./tmp
cat > ./tmp/index.html <<EOF
<!DOCTYPE html>
<meta charset="utf-8">
<meta http-equiv="refresh" content="0; URL=../${{ steps.branch_name.outputs.BRANCH_NAME }}/book">
<link rel="canonical" href="../${{ steps.branch_name.outputs.BRANCH_NAME }}/book">
<meta http-equiv="refresh" content="0; URL=../${{ steps.docs_target.outputs.tag }}/book">
<link rel="canonical" href="../${{ steps.docs_target.outputs.tag }}/book">
EOF
if: startsWith(github.ref, 'refs/tags')
if: steps.docs_target.outputs.tag != ''

- name: Deploy index.html redirect file to tag
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./tmp
destination_dir: ./${{ steps.branch_name.outputs.BRANCH_NAME }}
destination_dir: ./${{ steps.docs_target.outputs.tag }}
keep_files: true
if: startsWith(github.ref, 'refs/tags')
if: steps.docs_target.outputs.tag != ''

- name: Create latest HTML redirect file
if: startsWith(github.ref, 'refs/tags')
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
run: |
mkdir ./latest
cat > ./latest/index.html <<EOF
<!DOCTYPE html>
<meta charset="utf-8">
<meta http-equiv="refresh" content="0; URL=../${{ steps.branch_name.outputs.BRANCH_NAME }}/book">
<link rel="canonical" href="../${{ steps.branch_name.outputs.BRANCH_NAME }}/book">
<meta http-equiv="refresh" content="0; URL=../${{ steps.docs_target.outputs.tag }}/book">
<link rel="canonical" href="../${{ steps.docs_target.outputs.tag }}/book">
Comment thread
cursor[bot] marked this conversation as resolved.
EOF

- name: Set latest to point to tag
Expand All @@ -172,4 +217,4 @@ jobs:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./latest/
destination_dir: ./latest/
if: startsWith(github.ref, 'refs/tags')
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
51 changes: 51 additions & 0 deletions .github/workflows/scripts/check-sdk-harness-version.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,20 @@ get_version() {
echo "$version"
}

if ! command -v toml >/dev/null 2>&1; then
printf "ERROR: toml-cli is required to check SDK dependency versions.\n" >&2
exit 1
fi

IFS=',' read -ra PACKAGES <<< "$PACKAGE_NAMES"
mismatch=0
for PACKAGE in "${PACKAGES[@]}"; do
VERSION_FIRST=$(get_version ./Cargo.toml "workspace.dependencies.$PACKAGE")
VERSION_SECOND=$(get_version ./test/src/sdk-harness/Cargo.toml "dependencies.$PACKAGE")
if [ -z "$VERSION_FIRST" ] || [ -z "$VERSION_SECOND" ]; then
printf "ERROR: Could not read %s from both workspace and SDK harness manifests.\n" "$PACKAGE" >&2
mismatch=1
fi
printf "$PACKAGE\n sway repo: $VERSION_FIRST\n sdk-harness: $VERSION_SECOND\n"
if [ "$VERSION_FIRST" != "$VERSION_SECOND" ]; then
printf "ERROR: Version mismatch for $PACKAGE\n"
Expand All @@ -30,3 +39,45 @@ if [ $mismatch -ne 0 ]; then
else
printf "\nAll specified package versions match.\n"
fi

# The public cargo-generate templates must use the same Rust SDK generation as
# the SDK harness tested above. Keep this list explicit so a new program-type
# template must opt into the compatibility check.
FUELS_VERSION=$(get_version ./Cargo.toml "workspace.dependencies.fuels")
TEMPLATES=(
"./templates/sway-predicate-test-rs/template/Cargo.toml"
"./templates/sway-script-test-rs/template/Cargo.toml"
"./templates/sway-test-rs/template/Cargo.toml"
)

template_mismatch=0
mapfile -t DISCOVERED_TEMPLATES < <(
find ./templates -mindepth 3 -maxdepth 3 -type f \
-path '*/template/Cargo.toml' | sort
)
if [ "${DISCOVERED_TEMPLATES[*]}" != "${TEMPLATES[*]}" ]; then
printf "ERROR: Public template manifest list is out of sync.\n" >&2
printf "Expected: %s\n" "${TEMPLATES[*]}" >&2
printf "Found: %s\n" "${DISCOVERED_TEMPLATES[*]}" >&2
template_mismatch=1
fi

for TEMPLATE in "${TEMPLATES[@]}"; do
TEMPLATE_VERSION=$(get_version "$TEMPLATE" "dev-dependencies.fuels")
if [ -z "$FUELS_VERSION" ] || [ -z "$TEMPLATE_VERSION" ]; then
printf "ERROR: Could not read fuels version from workspace or %s\n" "$TEMPLATE" >&2
template_mismatch=1
fi
printf "fuels\n sway repo: $FUELS_VERSION\n $TEMPLATE: $TEMPLATE_VERSION\n"
if [ "$FUELS_VERSION" != "$TEMPLATE_VERSION" ]; then
printf "ERROR: Rust SDK version mismatch for %s\n" "$TEMPLATE"
template_mismatch=1
fi
done

if [ $template_mismatch -ne 0 ]; then
printf "\nRust SDK versions in the public templates must match workspace.dependencies.fuels.\n"
exit 1
else
printf "\nAll public template Rust SDK versions match the Sway SDK harness.\n"
fi
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,21 @@ Sway is a language developed for the [Fuel](https://docs.fuel.network/docs/intro

## Documentation

For user documentation, including installing release builds, see the Sway Book: <https://fuellabs.github.io/sway/latest/>.
For user documentation, including installing release builds, see the latest released Sway Book: <https://fuellabs.github.io/sway/latest/>.

For Sway Standard library documentation, see: <https://fuellabs.github.io/sway/master/std/>
The documentation URLs describe different source versions:

Also view the technical reference for the Sway programming language: <https://fuellabs.github.io/sway/master/reference/>
- `latest` redirects to the most recently published Sway release.
- `vX.Y.Z` is documentation built from that exact Sway release tag.
- `master` is built from the default branch and may describe unreleased behavior.

These labels are Sway documentation versions. They are not Fuelup channel names and do not identify the toolchain activated on a Fuel network. Check the compiler you are running with `forc --version` and consult the [Fuelup channel documentation](https://install.fuel.network/master/concepts/channels.html) when selecting network-compatible tooling.

For Sway standard library documentation from the default branch, see <https://fuellabs.github.io/sway/master/std/>.

Also view the default-branch technical reference for the Sway programming language at <https://fuellabs.github.io/sway/master/reference/>.

The **Stable** Sway and Forc pages on `docs.fuel.network` are published by [`FuelLabs/docs-hub`](https://github.com/FuelLabs/docs-hub) from an explicitly selected Sway release. That selection can differ from both the newest upstream release and the compiler in a named Fuelup network channel.

## Building from Source

Expand Down
3 changes: 3 additions & 0 deletions docs/book/spell-check-custom-words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -282,3 +282,6 @@ decodable
encodable
Vec
hashable
revalidate
revalidated
executable's
6 changes: 6 additions & 0 deletions docs/book/src/advanced/assembly.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ Note that in the above example:

An important note is that the `ji` and `jnei` opcodes are not available within an `asm` block. For those looking to introduce control flow to `asm` blocks, it is recommended to surround smaller chunks of `asm` with control flow (`if`, `else`, and `while`).

## Optimization Guidance

Inline assembly is not automatically cheaper than Sway. Measurements with Forc `0.71.2` found wins only when assembly removed fixed-loop or branch scaffolding; straight-line arithmetic, and assembly placed inside the original Sway loop, were gas-neutral or regressed.

Compare `forc test --release` gas and release bytecode size independently. Preserve checked-overflow behavior, zero-divisor and shift guards, evaluation order, memory effects, and reserved-register rules. Isolate a measured assembly kernel behind a small typed Sway function, and retain a readable Sway implementation as an oracle to differential-test the assembly against over boundary inputs. Revalidate assembly after every compiler or FuelVM upgrade.

## Helpful Links

For examples of assembly in action, check out the [Sway standard library](https://github.com/FuelLabs/sway/tree/master/sway-lib-std).
Expand Down
9 changes: 9 additions & 0 deletions docs/book/src/blockchain-development/storage.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ To read a storage variable, you also need to use the `storage` keyword. You may
{{#include ../../../../examples/basic_storage_variables/src/main.sw:basic_storage_read}}
```

## Performance and Safety

The compiler does not always eliminate duplicate storage operations:

- load an invariant value once before a loop and pass it to helpers;
- write only changed state and move invariant writes outside loops;
- do not reuse a cached value across an external call unless the reachable callbacks cannot mutate it;
- benchmark an ABI entry point, because helper-only gas does not price a storage path that the benchmark never executes.

## Storing Structs

To store a struct in storage, each variable must be assigned in the `storage` block. This can be either my assigning the fields individually or using a public [constructor](../basics/methods_and_associated_functions.md#constructors) that can be evaluated to a constant during compilation.
Expand Down
2 changes: 2 additions & 0 deletions docs/book/src/examples/sway_applications.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

The [Sway-Applications](https://github.com/FuelLabs/sway-applications) Repository contains end-to-end example applications that are written in Sway in order to demonstrate what can be built.

> **Legacy examples:** These applications are version-pinned snapshots and are not continuously updated for the current Sway release or Fuel network toolchains. Read the repository's [status and toolchain matrix](https://github.com/FuelLabs/sway-applications#project-status-and-toolchains) before using an example. Treat old syntax, dependencies, transaction construction, and security patterns as historical until revalidated.

## Asset Management

- [Airdrop](https://github.com/FuelLabs/sway-applications/tree/master/airdrop) is an asset distribution program where users are able to claim assets given a valid merkle proof.
Expand Down
2 changes: 2 additions & 0 deletions docs/book/src/forc/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

Forc stands for Fuel Orchestrator. Forc provides a variety of tools and commands for developers working with the Fuel ecosystem, such as scaffolding a new project, formatting, running scripts, deploying contracts, testing contracts, and more. If you're coming from a Rust background, forc is similar to cargo.

The core `forc` executable is released from the [`FuelLabs/sway`](https://github.com/FuelLabs/sway) repository. Some network-facing plugins, including `forc-client` and `forc-node`, are released independently from [`FuelLabs/forc`](https://github.com/FuelLabs/forc). Consequently, a Sway compiler version is not a complete plugin compatibility matrix. Check each installed executable with `<command> --version`; when its version differs from this book's release, prefer that executable's `--help` output for exact flags.

If you are new to Forc, see the [Forc Project](https://docs.fuel.network/docs/sway/introduction/forc_project/) introduction section.

For a comprehensive overview of the Forc CLI commands, see the [Commands](./commands/index.md) section.
4 changes: 3 additions & 1 deletion docs/book/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

Welcome to the Sway programming language book 🌴.

> **Documentation version:** A `vX.Y.Z` URL is built from that exact Sway release tag. The [`latest`](https://fuellabs.github.io/sway/latest/) URL redirects to the most recently published release, while [`master`](https://fuellabs.github.io/sway/master/book/) describes the default branch and may include unreleased behavior. These are documentation versions, not Fuelup channel names. Run `forc --version` to identify the compiler you are using and consult the [Fuelup channel documentation](https://install.fuel.network/master/concepts/channels.html) before choosing tooling for a network.

**Q: Hi! What is Sway?**

Sway is a domain-specific programming language for implementing smart contracts on blockchain platforms, most notably for the [Fuel Virtual Machine (Fuel VM)](https://docs.fuel.network/docs/specs/fuel-vm/).
Expand Down Expand Up @@ -55,7 +57,7 @@ If you don't want to install anything just yet, you can use the [Sway Playground

**Q: Where can I find example Sway code?**

You can find example applications built with Sway in the [Sway Applications repository](https://github.com/FuelLabs/sway-applications) on GitHub. You can also find projects building on Fuel in the [Fuel ecosystem home](https://app.fuel.network/ecosystem).
You can find historical example applications built with Sway in the [Sway Applications repository](https://github.com/FuelLabs/sway-applications) on GitHub. That repository contains version-pinned legacy snapshots, so check its status matrix before copying an example into a current project. You can also find projects building on Fuel in the [Fuel ecosystem home](https://app.fuel.network/ecosystem).

**Q: What is the standard library?**

Expand Down
Loading
Loading