Skip to content

Commit

Permalink
Update and test the getting-started script (#5446)
Browse files Browse the repository at this point in the history
Here are some changes to the `getting-started.sh` scripts we have
advertised on top of the readme.

### Changes to the script

1. Change `echo` to a more portable `printf`.

On my machine, the script printed a literal `\n` string if run with
`bash`.
If I changed it to `echo -e`, then it printed a literal `-e` if run with
`sh`.

Changed it to `printf` which is more portable.

---

2. Template selection

The script proceeded to clone and build the `minimal` template, which is
not always what we want.
Added a selection prompt where the user can select one of the 3
templates, and choose if it should be built&run or not.
The user can also select no template at all - that way, we have a
starter of a dependencies-installation script.

---

3. Added some missing dependencies for some of the systems.

### A workflow testing the script

I propose a workflow, that will test the script using the
[expect](https://core.tcl-lang.org/expect/index) tool.
For each OS mentioned in the script (macOS, Ubuntu, Debian, Arch,
Fedora, OpenSUSE) we go through the script twice, and after that build
and run the template binary.

I'm using docker containers, so we start from scratch and make sure the
scripts installs all required dependencies - with the exception of
macOS, which I can't run from scratch in a container.

The jobs use a selected combination of OSes, shell interpreters (`bash`
or `sh`), and templates.
There is too much combinations to run them all, but I have [run it
once](https://github.com/paritytech-stg/polkadot-sdk/actions/runs/10509533645)
in staging to make sure all pass.

I'm adding a cron schedule because it can break without any code changes
in this repository (e.g. new `latest` release of a container).

---------

Co-authored-by: Oliver Tale-Yazdi <[email protected]>
  • Loading branch information
rzadp and ggwpez authored Sep 5, 2024
1 parent cf330cc commit 5e0ec3e
Show file tree
Hide file tree
Showing 2 changed files with 367 additions and 39 deletions.
296 changes: 296 additions & 0 deletions .github/workflows/check-getting-started.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,296 @@
name: Check the getting-started.sh script

# This workflow aims to make sure that the `getting-started.sh` script
# is functional and allows to build the templates
# on different operating systems.
#
# There are two jobs inside.
# One for systems that can run in a docker container, and one for macOS.
#
# Each job consists of:
# 1. Some necessary prerequisites for the workflow itself.
# 2. A first pass of the script, which will install dependencies and clone a template.
# 3. A second pass of the script, to make sure the behaviour is as expected.
# 4. Building the template - making sure it's buildable and runnable.
#
# The script is interacted with using the `expect` tool, which is available on all relevant systems.
# The steps are not re-used between macOS and other systems,
# because they are very similar but a little different.
# Additionally, macOS does NOT start from scratch here - for example, we have homebrew already installed.
#
# There are many combinations of systems, shells and templates.
# We test a selected handful of combinations here.

on:
pull_request:
paths:
- '.github/workflows/check-getting-started.yml'
- 'scripts/getting-started.sh'
schedule:
- cron: '0 5 * * *'
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
check-getting-started:
strategy:
fail-fast: true
matrix:
include:
- name: ubuntu
container: ubuntu
template: minimal
shell: bash
- name: debian
container: debian
template: parachain
shell: sh
- name: arch
container: archlinux
template: solochain
shell: sh
- name: fedora
container: fedora
template: parachain
shell: sh
- name: opensuse
container: opensuse/tumbleweed
template: solochain
shell: sh
runs-on: arc-runners-polkadot-sdk-beefy
container: ${{ matrix.container }}:latest
steps:
# A minimal amount of prerequisites required before we can run the actual getting-started script,
# which will install the rest of requirements.
- name: Install ubuntu/debian prerequisites
run: apt update && apt install -y expect sudo git
if: contains(matrix.name, 'ubuntu') || contains(matrix.name, 'debian')
- name: Install arch prerequisites
run: pacman -Syu --needed --noconfirm expect sudo git
if: contains(matrix.name, 'arch')
- name: Install fedora prerequisites
run: dnf --assumeyes install expect sudo git
if: contains(matrix.name, 'fedora')
- name: Install opensuse prerequisites
run: zypper install --no-confirm expect sudo git
if: contains(matrix.name, 'opensuse')

- name: Checkout
uses: actions/checkout@v4

- name: Set additional expect flags if necessary
run: |
# Add a debug flag to expect, if github is re-run with debug logging enabled.
[ "${{ runner.debug }}" = "1" ] && EXPECT_FLAGS="-d" || EXPECT_FLAGS=""
echo "EXPECT_FLAGS=${EXPECT_FLAGS}" >> $GITHUB_ENV
- name: Check the first run of the script
run: |
expect $EXPECT_FLAGS -c '
set timeout 240
spawn ${{ matrix.shell }} scripts/getting-started.sh
expect_after {
timeout { puts stderr "Timed out on an expect"; exit 1 }
eof { puts stderr "EOF received on an expect"; exit 1 }
}
expect -nocase "Detected ${{ matrix.name }}"
expect "Rust is not installed. Install it?" {
send "y\r"
expect "Proceed with standard installation (default - just press enter)" {
send "\r"
expect "Rust is installed now"
}
}
expect "Setup the Rust environment" {
send "y\r"
}
expect "start with one of the templates" {
send "y\r"
}
expect -re "(.)\\) ${{ matrix.template }} template" {
send "$expect_out(1,string)\r"
}
expect "compile the node?" {
send "n\r"
}
expect eof
'
timeout-minutes: 15

- name: Check the second run of the script
run: |
expect $EXPECT_FLAGS -c '
set timeout 120
spawn ${{ matrix.shell }} scripts/getting-started.sh
expect_after {
timeout { puts stderr "Timed out on an expect"; exit 1 }
eof { puts stderr "EOF received on an expect"; exit 1 }
}
expect "Rust already installed" {}
expect "Setup the Rust environment" {
send "n\r"
}
expect "start with one of the templates" {
send "y\r"
}
expect -re "(.)\\) ${{ matrix.template }} template" {
send "$expect_out(1,string)\r"
expect "directory already exists" {}
}
expect "compile the node?" {
send "n\r"
}
expect eof
'
timeout-minutes: 15

- name: Compile the node outside of the script
run: |
. "$HOME/.cargo/env"
cd ${{ matrix.template }}-template
cargo build --release
timeout-minutes: 120

- name: Check that the binary is executable
run: |
. "$HOME/.cargo/env"
cd ${{ matrix.template }}-template
cargo run --release -- --help
timeout-minutes: 5

check-getting-started-macos:
strategy:
fail-fast: true
matrix:
include:
- template: parachain
shell: sh
- template: solochain
shell: bash
runs-on: macos-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set additional expect flags if necessary
run: |
# Add a debug flag to expect, if github is re-run with debug logging enabled.
[ "${{ runner.debug }}" = "1" ] && EXPECT_FLAGS="-d" || EXPECT_FLAGS=""
echo "EXPECT_FLAGS=${EXPECT_FLAGS}" >> $GITHUB_ENV
- name: Check the first run of the script
run: |
expect $EXPECT_FLAGS -c '
set timeout 120
spawn ${{ matrix.shell }} scripts/getting-started.sh
expect_after {
timeout { puts stderr "Timed out on an expect"; exit 1 }
eof { puts stderr "EOF received on an expect"; exit 1 }
}
expect -nocase "Detected macOS"
expect "Homebrew already installed"
expect "Install cmake" {
send "y\r"
}
expect "Rust already installed" {}
expect "Setup the Rust environment" {
send "y\r"
}
expect "start with one of the templates" {
send "y\r"
}
expect -re "(.)\\) ${{ matrix.template }} template" {
send "$expect_out(1,string)\r"
}
expect "compile the node?" {
send "n\r"
}
expect eof
'
timeout-minutes: 15

- name: Check the second run of the script
run: |
expect $EXPECT_FLAGS -c '
set timeout 120
spawn ${{ matrix.shell }} scripts/getting-started.sh
expect_after {
timeout { puts stderr "Timed out on an expect"; exit 1 }
eof { puts stderr "EOF received on an expect"; exit 1 }
}
expect "Homebrew already installed"
expect "Install cmake" {
send "y\r"
}
expect "Rust already installed" {}
expect "Setup the Rust environment" {
send "n\r"
}
expect "start with one of the templates" {
send "y\r"
}
expect -re "(.)\\) ${{ matrix.template }} template" {
send "$expect_out(1,string)\r"
expect "directory already exists" {}
}
expect "compile the node?" {
send "n\r"
}
expect eof
'
timeout-minutes: 15

- name: Compile the node outside of the script
run: |
. "$HOME/.cargo/env"
cd ${{ matrix.template }}-template
cargo build --release
timeout-minutes: 120

- name: Check that the binary is executable
run: |
. "$HOME/.cargo/env"
cd ${{ matrix.template }}-template
cargo run --release -- --help
timeout-minutes: 5
Loading

0 comments on commit 5e0ec3e

Please sign in to comment.