Skip to content

Support Actions concurrency syntax #32751

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

Zettat123
Copy link
Contributor

@Zettat123 Zettat123 commented Dec 7, 2024

Fix #24769
Fix #32662
Fix #33260

Depends on https://gitea.com/gitea/act/pulls/124

⚠️ BREAKING ⚠️

This PR removes the auto-cancellation feature added by #25716. Users need to manually add concurrency to workflows to control concurrent workflows or jobs.

@GiteaBot GiteaBot added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Dec 7, 2024
@github-actions github-actions bot added modifies/api This PR adds API routes or modifies them modifies/go Pull requests that update Go code modifies/migrations modifies/dependencies labels Dec 7, 2024
@Zettat123 Zettat123 force-pushed the support-actions-concurrency branch from 3551677 to fcf4517 Compare December 10, 2024 08:56
@lunny lunny added this to the 1.24.0 milestone Dec 16, 2024
@Zettat123 Zettat123 force-pushed the support-actions-concurrency branch from 52833e7 to 130f2a2 Compare December 17, 2024 01:49
@Zettat123 Zettat123 force-pushed the support-actions-concurrency branch 3 times, most recently from 461c7c1 to d5168a2 Compare January 6, 2025 06:16
@Zettat123 Zettat123 force-pushed the support-actions-concurrency branch from e038ed2 to f77f266 Compare January 10, 2025 06:00
@Zettat123 Zettat123 changed the title WIP: Support concurrency for Actions WIP: Support Actions concurrency syntax Jan 15, 2025
@Zettat123 Zettat123 force-pushed the support-actions-concurrency branch from ad71599 to 8f5948b Compare January 15, 2025 03:03
@Zettat123

This comment was marked as resolved.

wxiaoguang added a commit that referenced this pull request Jan 15, 2025
)

Move the main logic of `generateTaskContext` and `findTaskNeeds` to the
`services` layer.

This is a part of #32751, since we need the git context and `needs` to
parse the concurrency expressions.

---------

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
@Zettat123
Copy link
Contributor Author

I created a test workflow file like this

on:
  push:
    branches:
      - main

concurrency:
  group: example-group
  cancel-in-progress: true

jobs:
  job-1:
    runs-on: ubuntu-latest
    steps:
      - run: echo 'test1' && sleep 60

But it seems new run task will not cancel the old one.

Good catch. There was a bug when checking workflow-level concurrency groups. Now it has been fixed.

@GiteaBot GiteaBot added lgtm/need 1 This PR needs approval from one additional maintainer to be merged. and removed lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. labels May 20, 2025
@ChristopherHX
Copy link
Contributor

ChristopherHX commented May 22, 2025

I just tried this, with workflow

on: push
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
jobs:
  test:
    strategy:
      fail-fast: false
      matrix:
        no:
        - 1
        - 2
        - 3
        - 4
        - 5
    runs-on: ubuntu-latest
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
    - name: Run tests
      run: |
        echo ${{ github.run_id }} > "/tmp/test.txt"
    - uses: christopherhx/gitea-upload-artifact@v4
      with:
        path: test.txt
        name: test
  • Without any connected act_runner I pushed this via automation.
  • pushed a second file
  • Connect a single act_runner
  • All good first workflow cancelled, last push succeeded 👍
  • Now rerun all jobs of the previously cancelled run
  • Rerun all jobs latest previously successful run (directly after the other rerun)
  • latest previously successful rerun is cancelled and the rerun of "previously cancelled" succeeded

I expected the same result as on initial push, same order opposite behavior

Maybe you could provide me some insights, or I am going to debug this myself and share you my findings

What works good so far

  • Pushing two workflows without concurrency, I like this

@@ -53,6 +53,10 @@ func PickTask(ctx context.Context, runner *actions_model.ActionRunner) (*runnerv
return nil
}

if err := CancelJobsByJobConcurrency(ctx, t.Job); err != nil {
Copy link
Contributor

@ChristopherHX ChristopherHX May 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is cancelling implicitly a newer (re)run while a task is picked by an older (re)run and seems to be the cause for the behavior I described just before

I would expect only scheduling a job updates concurrency, since I am still using GitHub Actions side by side

Rerun all jobs didn't cancel the older run, which is already an error state.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rerun all jobs didn't cancel the older run, which is already an error state.

Status fixed, by respecting workflow concurrency in rerun all jobs.

Comment on lines +252 to +266
// cancel previous jobs in the same concurrency group
previousJobs, err := db.Find[ActionRunJob](ctx, &FindRunJobOptions{
RepoID: job.RepoID,
ConcurrencyGroup: job.ConcurrencyGroup,
Statuses: []Status{StatusRunning, StatusWaiting, StatusBlocked},
})
if err != nil {
return cancelledJobs, fmt.Errorf("find previous jobs: %w", err)
}
previousJobs = slices.DeleteFunc(previousJobs, func(j *ActionRunJob) bool { return j.ID == job.ID })
cjs, err := CancelJobs(ctx, previousJobs)
if err != nil {
return cancelledJobs, fmt.Errorf("cancel previous jobs: %w", err)
}
cancelledJobs = append(cancelledJobs, cjs...)
Copy link
Contributor

@ChristopherHX ChristopherHX May 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect that job concurrency key cancels equal workflow concurrency if defined on job level.

Based on my experience workflow and job concurrency use the same pool of concurrency keys. (deadlock handling required)

and CancelPreviousJobsByRunConcurrency to not be called here (EDIT 2 idk how this PR currently works, might break everything if not replaced)

e.g.

jobs:
  _:
    concurrency: test

cancels workflow

concurrency: test

In response of the unexpected behavior I have seen

EDIT
If we add an optional job / string parameter to CancelPreviousJobsByRunConcurrency , so the concurrency group of the job can be provided to replace the run concurrency key would fulfill my expectation, I guess.

@seriouz
Copy link

seriouz commented Jul 8, 2025

Any news on this? Is this still planed for 1.25.0?

@ChristopherHX
Copy link
Contributor

@Zettat123 I would try to fix my findings here and resolve the conflicts, but I have no access to this Pullrequest (Maintainer with read only access).

Allowing to queue up Workflows again is very nice, since I am not in favor of auto concurrency of length 1.

For own CI feedback I need create a new (draft) PR including all commits from here.

Then there are multiple options

  • I create a PR against the PR branch
  • You push my changes to your branch
  • We continue discussing on my followup PR

Thank you for all your work on this so far :).

@wxiaoguang
Copy link
Contributor

If you'd like to work with others' PRs often, maybe you can ask @go-gitea/technical-oversight-committee or some core members like @lunny to apply a merger's access, then you can edit PRs directly

@ChristopherHX
Copy link
Contributor

I would expect this to happen < 5 times per year. I actually only applied as maintainer due to work with others' PRs. I will ask formally in discord.

@ChristopherHX
Copy link
Contributor

New Defect found, needs fixing in gitea/act

invalid jobs: yaml: unmarshal errors:\n  line 4: cannot unmarshal !!str `test` into model.RawConcurrency

workflow

on: push
jobs:
  test:
    concurrency: test
    runs-on: ubuntu-latest
    steps:
    - name: Checkout code
      uses: actions/checkout@v4

short syntax not parseable.

Do we have this bug in act_runner as well? Do we have this bug in Gitea already?

@Naxdy
Copy link
Contributor

Naxdy commented Jul 18, 2025

One thing that I've noticed while running it is that manually cancelling a job that is blocking another job will not start the blocked job. You have to manually cancel & re-run the blocked job for it to be picked up.

So, if e.g. you have a job with:

concurrency:
  group: main
  cancel-in-progress: false

And you push twice to main, then cancel the job that was created first, the second job will never start.

@ChristopherHX ChristopherHX marked this pull request as draft July 18, 2025 13:41
@ChristopherHX
Copy link
Contributor

Thanks for pointing this out, I convert is to a draft until I am certain this works correctly.

I will add this scenario to the test cases and try to fix this

@Naxdy
Copy link
Contributor

Naxdy commented Jul 18, 2025

Sounds good. Feel free to ping / DM on discord if you want me to test something, or need something else. I've been running this for a while on my instance already.

@Zettat123
Copy link
Contributor Author

@ChristopherHX Sorry for the late reply, as I was busy with other work last month. Thank you for the improvements and bug fixes to this PR. Please feel free to update the code. I will also check if there are still issues with this PR.

@ChristopherHX
Copy link
Contributor

Hi,

No problem, once we both agree this is finished and can be merged I approve.

Good that you already looked at the cancellation problem.

I still think about if my code removal is correct or not in sense of not only let existing tests pass.

I had another behavior difference
If we do not have cancel in progress

  • GitHub Actions cancells all earlier blocked runs/jobs (only inprogress are kept if cancel-in-progress is false)
  • This PR queues up and runs every Run one by one

Would we want to add a custom boolean to implement both behaviors?

concurrency:
  cancel-pending: true # default true for GitHub Actions Compat, false for current implementation

Would we want to keep the behavior difference and document it?

if err != nil {
ctx.ServerError("GetRunByIndex", err)
}
if err := actions_service.EmitJobsIfReady(run.ID); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Queue EmitJobsIfReady from Actions Notifier Job and Workflow Completed?

(The event source used by workflow_run and workflow_job webhooks / action trigger)

I mean whatif the job is cancelled by abandoning or other reasons.

Less explicit code that has the same weakness towards all ways of cancellation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lgtm/need 1 This PR needs approval from one additional maintainer to be merged. modifies/go Pull requests that update Go code modifies/migrations pr/breaking Merging this PR means builds will break. Needs a description what exactly breaks, and how to fix it!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

workflow_dispatch allows only one job in a branch [Actions] Opt-out from auto-cancellation [Actions] Support concurrency syntax
8 participants