From 08735bc969e762f3ea68cae76123b174e1b1fd01 Mon Sep 17 00:00:00 2001 From: Alexey Burmistrov Date: Thu, 5 Jan 2023 15:28:42 +0200 Subject: [PATCH] feat: add context support BREAKING CHANGE: now all fsm interfaces contains context.Context as first argument --- .github/workflows/codeql-analysis.yml | 67 +++++++++++ .github/workflows/docker.yml | 6 +- .github/workflows/{ci.yml => go.yml} | 104 +++++++++++++----- .github/workflows/pr.yml | 9 +- .github/workflows/release.yml | 21 ++-- cmd/go-fsm/commands/actions_doc.go | 3 +- cmd/go-fsm/commands/actions_gen.go | 7 +- cmd/go-fsm/commands/gen.go | 5 +- cmd/go-fsm/commands/tests/actions_doc_test.go | 7 +- cmd/go-fsm/commands/tests/actions_gen_test.go | 18 +-- cmd/go-fsm/main.go | 1 + examples/transitions/order_fsm.go | 2 +- generator.go | 4 +- generator_test.go | 14 +-- tpl.go | 14 +-- 15 files changed, 198 insertions(+), 84 deletions(-) create mode 100644 .github/workflows/codeql-analysis.yml rename .github/workflows/{ci.yml => go.yml} (50%) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..78777a4 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,67 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [main] + pull_request: + # The branches below must be a subset of the branches above + branches: [main] + schedule: + - cron: "33 8 * * 3" + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + language: ["go"] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] + # Learn more: + # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed + + steps: + - name: Checkout repository + uses: actions/checkout@v3.1.0 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + # ℹī¸ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏ī¸ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index fbc62b2..7498c8e 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -34,16 +34,16 @@ jobs: echo ::set-output name=created::$(date -u +'%Y-%m-%dT%H:%M:%SZ') - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: Login to DockerHub - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and Push to Docker Hub - uses: docker/build-push-action@v2 + uses: docker/build-push-action@v3 if: github.event_name == 'release' || github.event_name == 'push' with: context: . diff --git a/.github/workflows/ci.yml b/.github/workflows/go.yml similarity index 50% rename from .github/workflows/ci.yml rename to .github/workflows/go.yml index 9d679f4..e2be059 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/go.yml @@ -1,35 +1,82 @@ -name: CI +name: Go on: push: tags: - v* branches: + - master - main + paths: + - "**.go" + - ".goreleaser.yml" + - ".golangci.yml" + - ".dockerignore" + - "Makefile" + - "rules.mk" + - "go.*" + - ".github/workflows/go.yml" pull_request: + paths: + - "**.go" + - ".goreleaser.yml" + - ".golangci.yml" + - ".dockerignore" + - "Makefile" + - "rules.mk" + - "go.*" + - ".github/workflows/go.yml" jobs: + goreleaser-dryrun: + strategy: + matrix: + golang: [1.17.x] + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3.1.0 + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: ${{ matrix.golang }} + - name: Cache Go modules + uses: actions/cache@v3.0.11 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ matrix.golang }}-v1-${{ hashFiles('**/go.sum') }} + restore-keys: ${{ runner.os }}-go-${{ matrix.golang }}-v1- + - name: Run GoReleaser (Dry Run) + uses: goreleaser/goreleaser-action@v3.2.0 + with: + version: latest + args: release --rm-dist --snapshot --skip-publish + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} golangci-lint: - name: golangci-lint runs-on: ubuntu-latest + strategy: + matrix: + golangci_lint: [v1.50] steps: - - uses: actions/checkout@v2 - - name: lint - uses: golangci/golangci-lint-action@v2 + - uses: actions/checkout@v3.1.0 + - name: golangci-lint + uses: golangci/golangci-lint-action@v3.3.0 with: - version: v1.44 - args: --timeout=2m + version: ${{ matrix.golangci_lint }} github-token: ${{ secrets.GITHUB_TOKEN }} + args: --timeout=2m + only-new-issues: false + working-directory: . tests-on-windows: needs: golangci-lint # run after golangci-lint action to not produce duplicated errors runs-on: windows-latest strategy: matrix: - golang: - - 1.17.x + golang: [1.17.x] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3.1.0 - name: Install Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v3 with: go-version: ${{ matrix.golang }} - name: Run tests on Windows @@ -40,23 +87,21 @@ jobs: runs-on: macos-latest strategy: matrix: - golang: - - 1.17.x + golang: [1.17.x] env: OS: macos-latest GOLANG: ${{ matrix.golang }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3.1.0 - name: Install Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v3 with: go-version: ${{ matrix.golang }} - - uses: actions/cache@v1 + - uses: actions/cache@v3.0.11 with: path: ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ matrix.golang }}-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go-${{ matrix.golang }}- + key: ${{ runner.os }}-go-${{ matrix.golang }}-v1-${{ hashFiles('**/go.sum') }} + restore-keys: ${{ runner.os }}-go-${{ matrix.golang }}-v1- - name: Compile the project run: make go.install - name: Run tests on Unix-like operating systems @@ -67,9 +112,9 @@ jobs: git --no-pager diff go.mod go.sum git --no-pager diff --quiet go.mod go.sum - name: Upload coverage to Codecov - uses: codecov/codecov-action@v1 + uses: codecov/codecov-action@v3.1.1 with: - #token: ${{ secrets.CODECOV_TOKEN }} + token: ${{ secrets.CODECOV_TOKEN }} file: ./coverage.txt flags: unittests env_vars: OS,GOLANG @@ -86,19 +131,18 @@ jobs: OS: ubuntu-latest GOLANG: ${{ matrix.golang }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3.1.0 - name: Install Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v3 with: go-version: ${{ matrix.golang }} - - uses: actions/cache@v1 + - uses: actions/cache@v3.0.11 with: path: ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ matrix.golang }}-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go-${{ matrix.golang }}- - - name: Build the project - run: make go.build + key: ${{ runner.os }}-go-${{ matrix.golang }}-v1-${{ hashFiles('**/go.sum') }} + restore-keys: ${{ runner.os }}-go-${{ matrix.golang }}-v1- + - name: Compile the project + run: make go.install - name: Check go.mod and go.sum run: | go mod tidy -v @@ -107,7 +151,7 @@ jobs: - name: Run tests on Unix-like operating systems run: make unittest - name: Upload coverage to Codecov - uses: codecov/codecov-action@v1 + uses: codecov/codecov-action@v3.1.1 with: token: ${{ secrets.CODECOV_TOKEN }} file: ./coverage.txt diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 92d9f6b..c9c5b86 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -1,8 +1,9 @@ name: PR on: + #pull_request_target: pull_request: - branches: [main] + branches: [master, main] issue_comment: types: [edited] @@ -11,10 +12,10 @@ jobs: name: Release-Notes Preview runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3.1.0 - run: | git fetch --prune --unshallow --tags - - uses: snyk/release-notes-preview@v1.6.1 + - uses: snyk/release-notes-preview@v1.6.2 with: releaseBranch: main env: @@ -25,7 +26,7 @@ jobs: name: Documentation runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3.1.0 with: depth: 1 - uses: K-Phoen/action-misspell@master diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 515968c..8eeb4f3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,38 +2,41 @@ name: Release on: push: branches: + - master - main jobs: release: name: releaser runs-on: ubuntu-latest + strategy: + matrix: + golang: [1.17.x] steps: - name: Checkout - uses: actions/checkout@master + uses: actions/checkout@v3.1.0 - name: Unshallow run: git fetch --prune --unshallow - name: Run Semantic Release id: semantic - uses: codfish/semantic-release-action@v1 + uses: codfish/semantic-release-action@v2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Set up Go if: steps.semantic.outputs.new-release-published == 'true' - uses: actions/setup-go@v2 + uses: actions/setup-go@v3 with: - go-version: 1.17.x + go-version: ${{ matrix.golang }} - name: Cache Go modules if: steps.semantic.outputs.new-release-published == 'true' - uses: actions/cache@v1 + uses: actions/cache@v3.0.11 with: path: ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go- + key: ${{ runner.os }}-go-${{ matrix.golang }}-v1-${{ hashFiles('**/go.sum') }} + restore-keys: ${{ runner.os }}-go-${{ matrix.golang }}-v1- - name: Run GoReleaser if: steps.semantic.outputs.new-release-published == 'true' - uses: goreleaser/goreleaser-action@v2 + uses: goreleaser/goreleaser-action@v3.2.0 with: version: latest args: release --rm-dist diff --git a/cmd/go-fsm/commands/actions_doc.go b/cmd/go-fsm/commands/actions_doc.go index a2c435f..5dcaf2c 100644 --- a/cmd/go-fsm/commands/actions_doc.go +++ b/cmd/go-fsm/commands/actions_doc.go @@ -3,7 +3,6 @@ package commands import ( "bytes" "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -82,7 +81,7 @@ func ActionDocGenerate(trFile, output string) error { } var source []byte - source, _ = ioutil.ReadFile(output) + source, _ = os.ReadFile(output) md := goldmark.New( goldmark.WithExtensions(extension.GFM), diff --git a/cmd/go-fsm/commands/actions_gen.go b/cmd/go-fsm/commands/actions_gen.go index 8578b77..6e307f2 100644 --- a/cmd/go-fsm/commands/actions_gen.go +++ b/cmd/go-fsm/commands/actions_gen.go @@ -4,7 +4,6 @@ import ( "bytes" "encoding/json" "fmt" - "io/ioutil" "os" "path/filepath" "text/template" @@ -61,7 +60,7 @@ var ActionsGenCommand = &cli.Command{ } } - tpl, err := ioutil.ReadFile(c.String("template")) + tpl, err := os.ReadFile(c.String("template")) if err != nil { return cli.Exit(err, 1) } @@ -117,7 +116,7 @@ func actionsGenerate(trFile, outputDir, tpl string) error { return fmt.Errorf("failed to format generated code: %w", err) } - if err := ioutil.WriteFile(fileName, processedSource, 0o644); err != nil { + if err := os.WriteFile(fileName, processedSource, 0o644); err != nil { return fmt.Errorf("failed to write file %q: %w", fileName, err) } } @@ -142,7 +141,7 @@ func transitionsFromFile(name string) (fsm.Transitions, error) { decoder = yaml.Unmarshal } - data, err := ioutil.ReadFile(name) + data, err := os.ReadFile(name) if err != nil { return nil, err } diff --git a/cmd/go-fsm/commands/gen.go b/cmd/go-fsm/commands/gen.go index c218d65..d762e1b 100644 --- a/cmd/go-fsm/commands/gen.go +++ b/cmd/go-fsm/commands/gen.go @@ -3,7 +3,6 @@ package commands import ( "bytes" "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -143,7 +142,7 @@ func genAction(c *cli.Context) error { return err } - if err := ioutil.WriteFile(options.OutputFile, buf.Bytes(), 0o644); err != nil { + if err := os.WriteFile(options.OutputFile, buf.Bytes(), 0o644); err != nil { return err } @@ -153,7 +152,7 @@ func genAction(c *cli.Context) error { return err } - if err := ioutil.WriteFile(options.ActionGraphOutputFile, buf.Bytes(), 0o644); err != nil { + if err := os.WriteFile(options.ActionGraphOutputFile, buf.Bytes(), 0o644); err != nil { return err } } diff --git a/cmd/go-fsm/commands/tests/actions_doc_test.go b/cmd/go-fsm/commands/tests/actions_doc_test.go index a65daeb..fa98d60 100644 --- a/cmd/go-fsm/commands/tests/actions_doc_test.go +++ b/cmd/go-fsm/commands/tests/actions_doc_test.go @@ -4,7 +4,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "os" "strings" "testing" @@ -17,7 +16,7 @@ import ( func TestActionsDocCommand(t *testing.T) { const trsFile = "./test_data/transitions.json" var transitions fsm.Transitions - data, err := ioutil.ReadFile(trsFile) + data, err := os.ReadFile(trsFile) if err != nil { t.Fatal(err) } @@ -28,7 +27,7 @@ func TestActionsDocCommand(t *testing.T) { t.Run("first time generate", func(t *testing.T) { is := is.New(t) tmpDir := t.TempDir() - tmpFile, err := ioutil.TempFile(tmpDir, "README.md") + tmpFile, err := os.CreateTemp(tmpDir, "README.md") is.NoErr(err) is.NoErr(commands.ActionDocGenerate(trsFile, tmpFile.Name())) actions := transitions.Actions() @@ -45,7 +44,7 @@ func TestActionsDocCommand(t *testing.T) { t.Run("append actions, transitions updated", func(t *testing.T) { is := is.New(t) tmpDir := t.TempDir() - tmpFile, err := ioutil.TempFile(tmpDir, "README.md") + tmpFile, err := os.CreateTemp(tmpDir, "README.md") is.NoErr(err) want := `### book diff --git a/cmd/go-fsm/commands/tests/actions_gen_test.go b/cmd/go-fsm/commands/tests/actions_gen_test.go index 24333c7..03bc80d 100644 --- a/cmd/go-fsm/commands/tests/actions_gen_test.go +++ b/cmd/go-fsm/commands/tests/actions_gen_test.go @@ -3,7 +3,8 @@ package tests import ( "encoding/json" "flag" - "io/ioutil" + "io" + "os" "path/filepath" "strings" "testing" @@ -19,7 +20,7 @@ func TestActionsGenCommand(t *testing.T) { is := is.New(t) app := &cli.App{ - Writer: ioutil.Discard, + Writer: io.Discard, ExitErrHandler: func(_ *cli.Context, _ error) {}, } set := flag.NewFlagSet("test", 0) @@ -38,7 +39,7 @@ func TestActionsGenCommand(t *testing.T) { tempDir := t.TempDir() app := &cli.App{ - Writer: ioutil.Discard, + Writer: io.Discard, ExitErrHandler: func(_ *cli.Context, _ error) {}, } set := flag.NewFlagSet("test", 0) @@ -59,7 +60,7 @@ func TestActionsGenCommand(t *testing.T) { tempDir := t.TempDir() app := &cli.App{ - Writer: ioutil.Discard, + Writer: io.Discard, ExitErrHandler: func(_ *cli.Context, _ error) {}, } set := flag.NewFlagSet("test", 0) @@ -80,7 +81,7 @@ func TestActionsGenCommand(t *testing.T) { tempDir := t.TempDir() app := &cli.App{ - Writer: ioutil.Discard, + Writer: io.Discard, ExitErrHandler: func(_ *cli.Context, _ error) {}, } set := flag.NewFlagSet("test", 0) @@ -93,9 +94,9 @@ func TestActionsGenCommand(t *testing.T) { c := cli.NewContext(app, set, nil) err := commands.ActionsGenCommand.Run(c) is.NoErr(err) - files, err := ioutil.ReadDir(tempDir) + files, err := os.ReadDir(tempDir) is.NoErr(err) - trsData, err := ioutil.ReadFile("./test_data/transitions.json") + trsData, err := os.ReadFile("./test_data/transitions.json") is.NoErr(err) var trs fsm.Transitions is.NoErr(json.Unmarshal(trsData, &trs)) @@ -103,7 +104,8 @@ func TestActionsGenCommand(t *testing.T) { is.True(len(actions) == len(files)) for _, v := range files { is.True(filepath.Ext(v.Name()) == ".go") - is.True(v.Size() > 0) + info, _ := v.Info() + is.True(!v.IsDir() && info.Size() > 0) is.True(fsm.InStrings(actions, strings.TrimSuffix(v.Name(), ".go"))) } }) diff --git a/cmd/go-fsm/main.go b/cmd/go-fsm/main.go index aaa2459..11613e8 100644 --- a/cmd/go-fsm/main.go +++ b/cmd/go-fsm/main.go @@ -35,6 +35,7 @@ func main() { } // These values are private which ensures they can only be set with the build flags. +// //nolint:unused var ( version = "unknown" diff --git a/examples/transitions/order_fsm.go b/examples/transitions/order_fsm.go index d25f240..c728eb5 100644 --- a/examples/transitions/order_fsm.go +++ b/examples/transitions/order_fsm.go @@ -8,7 +8,7 @@ import ( ) // DO NOT EDIT! -// This code is generated with http://github.com/MrEhbr/fsm tool +// This code is generated with http://github.com/MrEhbr/go-fsm tool //go:generate fsm gen -s Order -f State -o order_fsm.go -t transitions.json diff --git a/generator.go b/generator.go index 7a5a84f..aa13443 100644 --- a/generator.go +++ b/generator.go @@ -8,7 +8,7 @@ import ( "go/constant" "go/types" "io" - "io/ioutil" + "os" "path/filepath" "strconv" "strings" @@ -95,7 +95,7 @@ func NewGenerator(opt Options) (*Generator, error) { decoder = yaml.Unmarshal } - data, err := ioutil.ReadFile(opt.TransitionsFile) + data, err := os.ReadFile(opt.TransitionsFile) if err != nil { return nil, fmt.Errorf("failed to read transitions file: %w", err) } diff --git a/generator_test.go b/generator_test.go index 397d367..2ad0a12 100644 --- a/generator_test.go +++ b/generator_test.go @@ -2,7 +2,7 @@ package fsm import ( "fmt" - "io/ioutil" + "os" "path/filepath" "strings" "testing" @@ -138,7 +138,7 @@ type Order struct { }` const transitions = `[{"from": ["CREATED"],"to": "STARTED","event": "place_order"}]` - f, err := ioutil.TempFile(t.TempDir(), "trs") + f, err := os.CreateTemp(t.TempDir(), "trs") if err != nil { t.Fatal(err) } @@ -211,7 +211,7 @@ type Order struct { }` const transitions = `[{"from": ["CREATED"],"to": "STARTED","event": "place_order"}]` - f, err := ioutil.TempFile(t.TempDir(), "*_trs.json") + f, err := os.CreateTemp(t.TempDir(), "*_trs.json") if err != nil { t.Fatal(err) } @@ -259,7 +259,7 @@ type Order struct { - from: CREATED to: STARTED event: place_order` - f, err := ioutil.TempFile(t.TempDir(), "*_trs.yml") + f, err := os.CreateTemp(t.TempDir(), "*_trs.yml") if err != nil { t.Fatal(err) } @@ -308,7 +308,7 @@ type Order struct { - CREATED to: STARTED event: place_order` - f, err := ioutil.TempFile(t.TempDir(), "*_trs.yml") + f, err := os.CreateTemp(t.TempDir(), "*_trs.yml") if err != nil { t.Fatal(err) } @@ -362,12 +362,12 @@ func createPackage(pkg, dir string, src []byte) (string, error) { mod := fmt.Sprintf(`module %s go 1.16`, pkg) - if err := ioutil.WriteFile(filepath.Join(dir, "go.mod"), []byte(mod), 0o666); err != nil { + if err := os.WriteFile(filepath.Join(dir, "go.mod"), []byte(mod), 0o666); err != nil { return "", err } fpath := filepath.Join(dir, pkg+".go") - if err := ioutil.WriteFile(fpath, src, 0o666); err != nil { + if err := os.WriteFile(fpath, src, 0o666); err != nil { return "", err } diff --git a/tpl.go b/tpl.go index b6f05c2..afe5734 100644 --- a/tpl.go +++ b/tpl.go @@ -2,7 +2,7 @@ package fsm var fsmTemplate = `package {{.Package.Name}} // DO NOT EDIT! -// This code is generated with http://github.com/MrEhbr/fsm tool +// This code is generated with http://github.com/MrEhbr/go-fsm tool {{ if not .Options.DisableGoGenerate}} //{{"go:generate"}} go-fsm gen -s {{.Options.Struct}} -f {{.Options.StateField}} -o {{ base .Options.OutputFile }} @@ -20,9 +20,9 @@ type ( Actions []string } // {{.Struct.Name}}Handle handles transitions action - {{.Struct.Name}}HandleAction func(action string, transition {{.Struct.Name}}Transition, obj *{{.Struct.Name}}) error + {{.Struct.Name}}HandleAction func(ctx context.Context, action string, transition {{.Struct.Name}}Transition, obj *{{.Struct.Name}}) error // Save state to external storage - {{.Struct.Name}}PersistState func(obj *{{.Struct.Name}}, state {{.Struct.StateType}}) error + {{.Struct.Name}}PersistState func(ctx context.Context, obj *{{.Struct.Name}}, state {{.Struct.StateType}}) error // {{.Struct.Name}}StateMachine is a FSM that can handle transitions of a lot of objects. eventHandler and transitions are configured before use them. {{.Struct.Name}}StateMachine struct { transitions []{{.Struct.Name}}Transition @@ -70,7 +70,7 @@ func New{{.Struct.Name}}StateMachine(opts ...Option) *{{.Struct.Name}}StateMachi } // ChangeState fires a event and if event succeeded then change state. -func (m *{{.Struct.Name}}StateMachine) ChangeState(event string, obj *{{.Struct.Name}}) error { +func (m *{{.Struct.Name}}StateMachine) ChangeState(ctx context.Context, event string, obj *{{.Struct.Name}}) error { trans, ok := m.findTransMatching(obj.{{.Struct.StateField}}, event) if !ok { return fmt.Errorf("cannot find transition for event [%s] when in state [%v]", event, obj.{{.Struct.StateField}}) @@ -78,7 +78,7 @@ func (m *{{.Struct.Name}}StateMachine) ChangeState(event string, obj *{{.Struct. if len(trans.BeforeActions) > 0 && m.actionHandler != nil { for _, action := range trans.BeforeActions { - if err := m.actionHandler(action, trans, obj); err != nil { + if err := m.actionHandler(ctx, action, trans, obj); err != nil { if errors.Is(err, Err{{.Struct.Name}}FsmSkip) { return nil } @@ -89,7 +89,7 @@ func (m *{{.Struct.Name}}StateMachine) ChangeState(event string, obj *{{.Struct. } if m.persister != nil { - if err := m.persister(obj, trans.To); err != nil { + if err := m.persister(ctx, obj, trans.To); err != nil { return err } } @@ -99,7 +99,7 @@ func (m *{{.Struct.Name}}StateMachine) ChangeState(event string, obj *{{.Struct. if len(trans.Actions) > 0 && m.actionHandler != nil { var errs error for _, action := range trans.Actions { - if err := m.actionHandler(action, trans, obj); err != nil { + if err := m.actionHandler(ctx, action, trans, obj); err != nil { errs = multierror.Append(errs, fmt.Errorf("%w. action [%s] return error: %s", Err{{.Struct.Name}}FsmAction, action, err)) } }