Awesome
smalltalkCI
Community-supported framework for testing Smalltalk projects on Linux, OS X, and Windows with built-in support for GitHub Actions, GitLab CI/CD, Travis CI, and AppVeyor.
It is inspired by builderCI and aims to provide a uniform and easy way to load and test Smalltalk projects.
Table Of Contents
- Features
- How to set up Continuous Integration for your Smalltalk project
- How to test your Smalltalk project locally
- List of Supported Images
- Templates
- Further Configuration
- Contributing
- Projects using smalltalkCI
Features
- Compatible across different Smalltalk dialects (Squeak, Pharo, GemStone)
- Runs on GitHub Actions, GitLab CI, Travis CI, AppVeyor, and other CI services
- Simple configuration via
.smalltalk.ston
,setup-smalltalkCI
action,.gitlab-ci.yml
,.travis.yml
, andappveyor.yml
- Supports Linux, macOS, and Windows and can be run locally (e.g. for debugging purposes)
- Supports coverage testing
- Exports test results in the JUnit XML format as part of the build log
<a name="how-to-ci"/>How To Set Up Continuous Integration For Your Smalltalk Project
- Export your project in a compatible format (e.g., Tonel or FileTree).
- Enable a CI service for your repository (e.g., GitHub Actions).
- Create a config file for your CI service (see below for templates) and specify the Smalltalk image(s) you want your project to be tested against.
- Create a
.smalltalk.ston
file and specify how to load and test your project. - Push all of this to your repository and enjoy your fast Smalltalk builds!
<a name="how-to-local"/>How To Test Your Smalltalk Project Locally
You can use smalltalkCI to run your project's tests locally. Just clone or download smalltalkCI and then you can initiate a local build in headful mode like this:
bin/smalltalkci -s <IMAGE> --headful /path/to/your/project/.smalltalk.ston
<IMAGE>
can be one of the supported images. You may also want to
have a look at all supported options.
On Windows, you need to run smalltalkCI from a Bash shell such as Git Bash or Cygwin, MinGW, or MSYS2.
Please note: All builds will be stored in _builds
within smalltalkCI's
directory. You may want to delete single or all builds if you don't need them as
they can take up a lot of space on your drive.
<a name="images"/>List of Supported Images
Squeak | Pharo | GemStone | Moose | GToolkit |
---|---|---|---|---|
Squeak64-trunk | Pharo64-alpha | GemStone64-3.6.x | Moose64-trunk | GToolkit64-release |
Squeak64-6.0 | Pharo64-stable | GemStone64-3.5.8 | Moose64-12 | |
Squeak64-5.3 | Pharo64-13 | GemStone64-3.5.7 | Moose64-11 | |
Squeak64-5.2 | Pharo64-12 | GemStone64-3.5.6 | Moose64-10 | |
Squeak64-5.1 | Pharo64-11 | GemStone64-3.5.5 | Moose64-9.0 | |
Squeak32-trunk | Pharo64-10 | Gemstone64-3.5.4 | Moose64-8.0 | |
Squeak32-6.0 | Pharo64-9.0 | GemStone64-3.5.3 | ||
Squeak32-5.3 | Pharo64-8.0 | |||
Squeak32-5.2 | Pharo64-7.0 | |||
Squeak32-5.1 | Pharo64-6.1 | |||
Squeak32-5.0 | Pharo64-6.0 | |||
Squeak32-4.6 | Pharo32-alpha | |||
Squeak32-4.5 | Pharo32-stable | |||
Pharo32-12 | ||||
Pharo32-11 | ||||
Pharo32-10 | ||||
Pharo32-9.0 | ||||
Pharo32-8.0 | ||||
Pharo32-7.0 | ||||
Pharo32-6.1 | ||||
Pharo32-6.0 | ||||
Pharo32-5.0 | ||||
Pharo32-4.0 | ||||
Pharo32-3.0 |
Templates
<a name="minimal-smalltalkston-template"/>Minimal .smalltalk.ston
Template
The following SmalltalkCISpec
will load BaselineOfMyProject
using
Metacello/FileTree from the ./packages
directory in Squeak, Pharo, and
GemStone. See below how you can
customize your SmalltalkCISpec
.
SmalltalkCISpec {
#loading : [
SCIMetacelloLoadSpec {
#baseline : 'MyProject',
#platforms : [ #squeak, #pharo, #gemstone ]
}
]
}
GitHub Action Templates
For GitHub Action templates, please refer to the Marketplace listing of the
setup-smalltalkCI
action.
GitLab CI Template
<details> <summary><code>.gitlab-ci.yml</code></summary>image: hpiswa/smalltalkci
Squeak64Trunk:
script: smalltalkci -s "Squeak64-trunk"
Squeak325.1:
script: smalltalkci -s "Squeak32-5.1"
Pharo64Alpha:
script: smalltalkci -s "Pharo64-alpha"
Pharo327.0:
script: smalltalkci -s "Pharo32-7.0"
# ...
</details>
Travis CI Templates
<details> <summary><code>.travis.yml</code></summary>language: smalltalk
sudo: false
# Select operating system(s)
os:
- linux
- osx
# Select compatible Smalltalk image(s)
smalltalk:
- Squeak64-trunk
- Squeak64-5.1
- Squeak32-4.6
- Squeak32-4.5
# ...
- Pharo64-alpha
- Pharo64-stable
- Pharo64-7.0
- Pharo64-6.1
# ...
- Pharo32-alpha
- Pharo32-stable
- Pharo32-6.1
# ...
- GemStone64-3.5.3
- GemStone64-3.6.0
- GemStone64-3.6.5
# ...
# Override `script` to customize smalltalkCI invocation, e.g.:
#script:
# - smalltalkci .mysmalltalk1.ston
# - travis_wait smalltalkci .mysmalltalk2.ston
# Uncomment to enable caching (only useful for GemStone builds (3x faster))
#cache:
# directories:
# - $SMALLTALK_CI_CACHE
</details>
<details>
<summary><code>.travis.yml</code> with multiple smalltalkCI configurations</summary>
The build matrix can be expanded with multiple smalltalkCI configuration files
using the smalltalk_config
key:
language: smalltalk
sudo: false
smalltalk:
- Squeak64-trunk
- Pharo64-alpha
smalltalk_config:
- .smalltalk.ston
- .bleedingEdge.ston
The .bleedingEdge.ston
configuration may look like this:
SmalltalkCISpec {
#loading : [
SCIMetacelloLoadSpec {
...
#load : [ 'CoreWithExtras' ],
#version : #bleedingEdge
}
],
...
}
Resulting build matrix
Smalltalk | Config | OS |
---|---|---|
Squeak64-trunk | .smalltalk.ston | Linux |
Squeak64-trunk | .bleedingEdge.ston | Linux |
Pharo64-alpha | .smalltalk.ston | Linux |
Pharo64-alpha | .bleedingEdge.ston | Linux |
It is possible to add additional jobs to the build matrix
using the smalltalk_config
key:
language: smalltalk
sudo: false
os: osx
smalltalk:
- Squeak32-5.1
- Pharo32-6.0
matrix:
include:
- smalltalk: Squeak64-trunk
smalltalk_config: .bleedingEdge.ston
- smalltalk: Pharo64-alpha
smalltalk_config: .bleedingEdge.ston
allow_failures: # Allow bleeding edge builds to fail
- smalltalk_config: .bleedingEdge.ston
Resulting build matrix
Smalltalk | Config | OS |
---|---|---|
Squeak32-5.1 | .smalltalk.ston | macOS |
Pharo32-6.0 | .smalltalk.ston | macOS |
Squeak64-trunk | .bleedingEdge.ston | macOS |
Pharo64-alpha | .bleedingEdge.ston | macOS |
AppVeyor Templates
<details> <summary><code>appveyor.yml</code></summary># This is a 64-bit environment, so use 64-bit Cygwin
environment:
CYG_ROOT: C:\cygwin64
CYG_BASH: C:\cygwin64\bin\bash
CYG_CACHE: C:\cygwin64\var\cache\setup
CYG_EXE: C:\cygwin64\setup-x86_64.exe
CYG_MIRROR: http://cygwin.mirror.constant.com
SCI_RUN: /cygdrive/c/smalltalkCI-master/bin/smalltalkci
matrix:
# Currently, only Squeak and Pharo images are supported on AppVeyor.
- SMALLTALK: Squeak64-trunk
- SMALLTALK: Squeak64-5.0
- SMALLTALK: Pharo64-alpha
- SMALLTALK: Pharo64-6.0
# ...
platform:
- x64
install:
- '%CYG_EXE% -dgnqNO -R "%CYG_ROOT%" -s "%CYG_MIRROR%" -l "%CYG_CACHE%" -P unzip'
- ps: Start-FileDownload "https://github.com/hpi-swa/smalltalkCI/archive/master.zip" "C:\smalltalkCI.zip"
- 7z x C:\smalltalkCI.zip -oC:\ -y > NULL
build: false
test_script:
- '%CYG_BASH% -lc "cd $APPVEYOR_BUILD_FOLDER; exec 0</dev/null; $SCI_RUN"'
</details>
<details>
<summary><code>appveyor.yml</code> with additional jobs</summary>
It is possible to add additional jobs to the
build matrix using environment.matrix
as follows:
environment:
CYG_ROOT: C:\cygwin
CYG_BASH: C:\cygwin\bin\bash
CYG_CACHE: C:\cygwin\var\cache\setup
CYG_EXE: C:\cygwin\setup-x86.exe
CYG_MIRROR: http://cygwin.mirror.constant.com
SCI_RUN: /cygdrive/c/SMALLTALKCI-master/bin/smalltalkci
matrix:
- SMALLTALK: Squeak32-5.1
- SMALLTALK: Squeak64-trunk
SMALLTALK_CONFIG: .bleedingEdge.ston
- SMALLTALK: Pharo32-6.0
- SMALLTALK: Pharo64-alpha
SMALLTALK_CONFIG: .bleedingEdge.ston
platform:
- x86
install:
- '%CYG_EXE% -dgnqNO -R "%CYG_ROOT%" -s "%CYG_MIRROR%" -l "%CYG_CACHE%" -P unzip'
- ps: Start-FileDownload "https://github.com/hpi-swa/SMALLTALKCI/archive/master.zip" "C:\SMALLTALKCI.zip"
- 7z x C:\SMALLTALKCI.zip -oC:\ -y > NULL
build: false
test_script:
- '%CYG_BASH% -lc "cd $APPVEYOR_BUILD_FOLDER; exec 0</dev/null; $SCI_RUN $SMALLTALK_CONFIG"'
Resulting build matrix
Smalltalk | Config |
---|---|
Squeak32-5.1 | .smalltalk.ston |
Squeak64-trunk | .bleedingEdge.ston |
Pharo32-6.0 | .smalltalk.ston |
Pharo64-alpha | .bleedingEdge.ston |
Further Configuration
<a name="SmalltalkCISpec"/>Setting Up A Custom .smalltalk.ston
smalltalkCI requires a .smalltalk.ston
configuration file which can be
customized for a project to cover various use cases.
The .smalltalk.ston
must be a valid STON file and has to contain a
single SmalltalkCISpec
object.
This object can hold one or more load specifications in
#loading
and configurations for the TestCase selection
in #testing
.
SmalltalkCISpec {
#name : 'My Name', // Name of the SmalltalkCISpec (optional)
#loading : [
// List Of Load Specifications...
],
#testing : {
// TestCase Selection...
}
}
<a name="load-specs"/>Project Loading Specifications
smalltalkCI supports different formats for loading Smalltalk projects and for
each, there is a loading specification.
One or more of those loading specifications have to be provided in the
#loading
list as part of a SmalltalkCISpec
.
smalltalkCI will load all specifications that are compatible with the selected
Smalltalk image (specified via #platforms
).
SCIMetacelloLoadSpec
A SCIMetacelloLoadSpec
loads a project either via the specified Metacello
#baseline
or the Metacello
#configuration
. If a #directory
is specified,
the project will be loaded using FileTree/Metacello
from the given directory.
Otherwise, it will be loaded from the specified #repository
.
SCIMetacelloLoadSpec {
#baseline : 'MyProject', // Define MC Baseline
#configuration : 'MyProject', // Alternatively, define MC Configuration
#directory : 'src', // Path to source-code directory were are packages (i.e. 'packages' or 'src'), in case of packages are not on root
#failOn : [ #OCUndeclaredVariableWarning ], // Fail build on provided list of Warnings
#ignoreImage : true, // If true, Metacello will force a load of a package, overriding a previously existing one
#load : [ 'default' ], // Define MC load attributes
#onConflict : #useIncoming, // When there is a conflict between loaded sources and incoming sources (can be #useIncoming|#useLoaded)
#onUpgrade : #useIncoming, // When loaded sources are an older version than incoming sources (can be #useIncoming|#useLoaded)
#onWarningLog : true, // Log Warning messages to Transcript
#platforms : [ #squeak, #pharo, #gemstone ], // Define compatible platforms
#repository : 'http://smalltalkhub.com/mc/...', // Alternatively, define MC repository
#usernameEnvVar : 'GITHUB_USER', // Environment variable containing the username used for authentication
#passwordEnvVar : 'GITHUB_TOKEN', // Environment variable containing the password used for authentication
#useLatestMetacello : true, // Upgrade Metacello before loading
#version : '1.0.0' // Define MC version (for MC Configurations only)
#registerInIceberg : true // Pharo Only | Register the tested repository in Iceberg
}
SCIMonticelloLoadSpec
A SCIMonticelloLoadSpec
loads a project with Monticello. It is
possible to load the latest version of packages from a remote repository
(#packages
) or specific versions (#versions
).
SCIMonticelloLoadSpec {
#url : 'http://ss3.gemtalksystems.com/ss/...', // Define URL for repository
#packages : ['MyProject-Core', 'MyProject-Tests'], // Load packages and/or
#versions : ['MyProject-Core-aa.12'], // Load specific versions
#usernameEnvVar : 'USERNAME_VAR', // Environment variable containing the username used for authentication
#passwordEnvVar : 'PASSWORD_VAR', // Environment variable containing the password used for authentication
#platforms : [ #squeak, #pharo, #gemstone ] // Define compatible platforms
}
SCIGoferLoadSpec
A SCIGoferLoadSpec
works similar to a SCIMonticelloLoadSpec
, but uses
Gofer on top of Monticello to load a project.
SCIGoferLoadSpec {
#url : 'http://smalltalkhub.com/mc/...', // Define URL for repository
#packages : ['MyProject-Core', 'MyProject-Tests'], // Load packages and/or
#versions : ['MyProject-Core-aa.12'], // Load specific versions
#usernameEnvVar : 'USERNAME_VAR', // Environment variable containing the username used for authentication
#passwordEnvVar : 'PASSWORD_VAR', // Environment variable containing the password used for authentication
#platforms : [ #squeak, #pharo, #gemstone ] // Define compatible platforms
}
TestCase Selection
smalltalkCI runs a list of TestCases during a build.
By default, smalltalkCI will use a list of all TestCases that it has loaded into
the image.
It is possible to adjust this list using the #testing
slot.
In general, TestCases can be selected on class-level (#classes
), on
category-level (#categories
), on package-level (#packages
) and on
project-level (#projects
, GemStone only).
#classes
expects a list of class name symbols, #categories
and #packages
expect category names and prefixes or package names and prefixes respectively.
The default list can be replaced by a list of all TestCases that are present in
the image by setting #allTestCases
to true
.
Additionally, it is possible to add (#include
) or remove (#exclude
) classes
from this list.
The list can also be specified explicitly which means that only these
TestCases will run.
SmalltalkCISpec {
...
#testing : {
// Include specific TestCases
#include : {
#classes : [ #AnotherProjectTestCase ],
#categories : [ 'AnotherProject-Tests' ],
#packages : [ 'AnotherProject.*' ],
#projects : [ 'BaselineOfMyProject' ]
},
// Exclude specific TestCases from testing
#exclude : {
#classes : [ #AnotherProjectTestCase ],
#categories : [ 'AnotherProject-Tests' ],
#packages : [ 'AnotherProject.*' ],
#projects : [ 'ConfigurationOfMyOtherProject' ]
},
#allTestCases : true, // Run all TestCases in image
// Define TestCases explicitly
#classes : [ #MyProjectTestCase ],
#categories : [ 'MyProject-*' ],
#packages : [ 'MyProject.*' ],
#projects : [ 'BaselineOfMyProject' ],
// Other options
#defaultTimeout : 30, // In seconds (Squeak, and Pharo 6 or later)
#failOnSCIDeprecationWarnings : false, // Fail if a deprecated smalltalkCI API is used
#failOnZeroTests : false, // Pass builds that did not run any tests
#hidePassingTests : true, // Hide passing tests when printing to stdout
#serializeError: false // (default: true) Disable serialization of failing test case (e.g. with Fuel in Pharo)
}
}
Coverage Testing
See COVERAGE.md.
Custom Scripts
It is possible to run custom scripts before and after the loading and
testing phases (preLoading
, postLoading
, preTesting
, postTesting
).
smalltalkCI can file in single files, lists of files, and
SCICustomScript
s which can be used to only run certain scripts on certain
platforms.
SmalltalkCISpec {
#preLoading : 'scripts/preLoading.st',
#loading : ...,
#postLoading : [
'scripts/postLoading1.st',
'scripts/postLoading2.st'
],
#preTesting : SCICustomScript {
#path : 'scripts/preTesting.st',
#platforms : [ #squeak, #pharo, #gemstone ]
},
#testing : ...,
#postTesting : [
SCICustomScript {
#path : 'scripts/postTestingSqueak.st',
#platforms : [ #squeak ]
},
SCICustomScript {
#path : 'scripts/postTestingPharo.st',
#platforms : [ #pharo ]
}
]
}
Command Line Options
smalltalkCI has a couple of command line options that can be useful for debugging purposes or when used locally:
USAGE: bin/smalltalkci [options] /path/to/project/your_smalltalk.ston
This program prepares Smalltalk images/vms, loads projects, and runs tests.
OPTIONS:
--clean Clear cache and delete builds.
-d | --debug Enable debug mode.
-h | --help Show this help text.
--headful Open vm in headful mode and do not close image.
--image Custom image for build (Squeak/Pharo).
--install Install symlink to this smalltalkCI instance.
--print-env Print all environment variables used by smalltalkCI
--no-color Disable colored output
--no-tracking Disable collection of anonymous build metrics (Travis CI & AppVeyor only).
-s | --smalltalk Overwrite Smalltalk image selection.
--uninstall Remove symlink to any smalltalkCI instance.
-v | --verbose Enable 'set -x'.
--vm Custom VM for build (Squeak/Pharo).
EXAMPLE:
bin/smalltalkci -s "Squeak64-trunk" --headful /path/to/project/.smalltalk.ston
Collection Of Anonymous Build Metrics
smalltalkCI collects anonymous build metrics (Smalltalk dialect, CI environment,
build status, build duration) for public repositories when running on a supported
CI platform. This helps to identify build errors caused by smalltalkCI updates
and therefore helps to improve the service. It is possible to opt-out by using
the --no-tracking
option.
Travis-specific Options
Travis Timeouts
Jobs on Travis CI timeout if they don't produce output for
more than 10 minutes. In the case of long-running tests, it
is possible to increase this timeout by setting $SMALLTALK_CI_TIMEOUT
in your
.travis.yml
to a value greater than 10:
env:
- SMALLTALK_CI_TIMEOUT=30
The above sets the timeout to 30 minutes. Please note that Travis CI enforces a total build timeout of 50 minutes.
Using A Different smalltalkCI Branch Or Fork
By default, the smalltalkCI master branch is used to perform a build. It is
possible to select a different smalltalkCI branch or fork for testing/debugging
purposes by adding the following to the .travis.yml
:
smalltalk_edge:
source: hpi-swa/smalltalkCI
branch: dev
Contributing
Please feel free to open issues or to send pull requests if you'd like to discuss an idea or a problem.
Projects Using smalltalkCI
In alphabetical order:
- @ba-st: Buoy, RenoirSt, Willow.
- @Cormas: Cormas.
- @dalehenrich: obex, tode.
- @DuneSt: Heimdall, MaterialDesignLite, PrismCodeDisplayer.
- @HPI-BP2015H: squeak-parable.
- @hpi-swa: animations, Ohm-S, signals, Sandblocks, Squot, vivide, widgets.
- @hpi-swa-lab: Babylonian Programming/Smalltalk, Squeak by Example, Squeak Inbox Talk.
- @HPI-SWA-Teaching: Algernon-Launcher, AutoTDD, Koans, Morphic Testing Framework, Poppy Print, SpreadSheetTool, TelegramClient, SwaLint.
- @LinqLover: create-image, SimulationStudio, TelegramBot, XmasDecorations.
- @marianopeck: OSSubprocess, FFICHeaderExtractor.
- @Metacello: metacello.
- @newapplesho: aws-sdk-smalltalk, elasticsearch-smalltalk, mixpanel-smalltalk, OpenExchangeRates, pardot-smalltalk, salesforce-smalltalk, sendgrid-smalltalk, twilio-smalltalk.
- @ObjectProfile: Roassal2.
- @OpenPonk: borm-editor, borm-model, class-editor, demo-editor, fsm-editor.
- @OpenSmalltalk: opensmalltalk-vm.
- @pharo-project: pharo-project-proposals.
- @PolyMathOrg: PolyMath.
- @SeasideSt: Grease, Parasol, Seaside.
- @SergeStinckwich: PlayerST.
- @squeak-smalltalk: squeak-app, squeak-filesystem, squeak-ston, squeak-tonel.
- @theseion: Fuel.
- @Uko: GitHubcello, QualityAssistant, Renraku.
- @UMMISCO: Kendrick.
- @zecke: osmo-smsc.
- More Projects...
Feel free to send a PR to add your Smalltalk project to the
list. Please add [ci skip]
to your commit message.