Skip to content
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

tests: split workflow into smaller parts #14689

Conversation

maykathm
Copy link
Contributor

@maykathm maykathm commented Nov 5, 2024

This separates out the following jobs into separate workflows:

  • snap builds
  • unit tests (including cross-distro)
  • static checks
  • spread

I thought it could be beneficial, from a maintenance perspective, to keep run labels in the top-level test.yaml file. That way the top-level yaml takes on the responsibility of deciding OSes and orchestrating and parameterizing jobs while the called workflows is only responsible for its jobs logic, given the inputs.

I kept matrix logic at the test.yaml level to allow for greater future reuse.

For example, instead of using a matrix strategy, one can simply call the workflow with the various parameters. So while the following works:

  unit-tests-cross-distro:
    uses: ./.github/workflows/unit-tests.yaml
    needs: [static-checks]
    with:
      runs-on: ubuntu-latest
      distro: ${{ matrix.distro }}
    strategy:
      fail-fast: false
      matrix:
        distro:
          - fedora:latest
          - opensuse/tumbleweed

one can also write:

  unit-tests-fedora:
    uses: ./.github/workflows/unit-tests.yaml
    needs: [static-checks]
    with:
      runs-on: ubuntu-latest
      distro: fedora:latest

  unit-tests-opensuse:
    uses: ./.github/workflows/unit-tests.yaml
    needs: [static-checks]
    with:
      runs-on: ubuntu-latest
      distro: opensuse/tumbleweed

@maykathm maykathm force-pushed the SNAPDENG-34130-split-workflow-into-smaller-parts branch 2 times, most recently from 589d075 to aa21f6f Compare November 5, 2024 15:08
Copy link

codecov bot commented Nov 5, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 78.98%. Comparing base (96ea7b0) to head (6e03b7c).
Report is 59 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #14689      +/-   ##
==========================================
+ Coverage   78.95%   78.98%   +0.03%     
==========================================
  Files        1084     1085       +1     
  Lines      146638   147313     +675     
==========================================
+ Hits       115773   116362     +589     
- Misses      23667    23723      +56     
- Partials     7198     7228      +30     
Flag Coverage Δ
unittests 78.98% <ø> (+0.03%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@maykathm maykathm force-pushed the SNAPDENG-34130-split-workflow-into-smaller-parts branch from aa21f6f to 8c0f1cf Compare November 6, 2024 09:40
@maykathm maykathm marked this pull request as ready for review November 7, 2024 12:41
Copy link
Contributor

@zyga zyga left a comment

Choose a reason for hiding this comment

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

I'm very happy to see this. Our CI pipeline was a bit of an evolutionary mess that made it bot slower and harder to understand.

Two notes:

  • Please double check that the state of the pipeline in master has not moved. As of Friday, 8th of November, there are conflicts suggesting that they did.
  • Please document workflow inputs so that it's easier to figure out stuff that's less than obvious (like version with the value of "pristine").

Lastly once this lands I'd love to see a follow up to clean up more of this that is now more evident. Things like reused preparation across workflows - local actions handle that very well.

Overall +1 but please resolve conflicts and ping for re-review just prior to merging.

with:
# needed for git commit history
fetch-depth: 0
# NOTE: checkout the code in a fixed location, even for forks, as this
Copy link
Contributor

Choose a reason for hiding this comment

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

I suspect this is not useful anymore but I think this is something we can explore in another cleanup pass.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

How about I add another task for myself after this PR is merged to do some cleanup? Since the file changes make reviewing this PR difficult, I think perhaps it would be better to have only reorganization in this PR and actual changes in another so that it's easy for reviewers to see the changes.

Copy link
Contributor

Choose a reason for hiding this comment

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

I suppose this is no longer an issue since we added go.mod support. Perhaps it's worth to check if we could simply use the project default location. FWIW, followup material.

if: ${{ inputs.unit-scenario == 'normal' }}
run: |
cd ${{ github.workspace }}/src/github.com/snapcore/snapd || exit 1
./run-checks --unit
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this should move to go test ./.... The reason for avoiding vendor directories is AFAIK long gone.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I would propose, as above, that making code changes be part of a follow-up task in cleaning up the actions. That's only because reviewing code across file changes is ugly.

.github/workflows/snap-builds.yaml Show resolved Hide resolved
.github/workflows/snap-builds.yaml Show resolved Hide resolved
.github/workflows/snap-builds.yaml Show resolved Hide resolved
path: ./src/github.com/snapcore/snapd

# Fetch base ref, needed for golangci-lint
- name: Fetching base ref ${{ github.base_ref }}
Copy link
Contributor

Choose a reason for hiding this comment

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

All of this typical setup can be broken out further and used across all the workflows. This can be a local action.

Copy link
Contributor Author

@maykathm maykathm Nov 8, 2024

Choose a reason for hiding this comment

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

After looking through the workflows, I believe the most sensible common point is the "downloading cached Debian dependencies, extracting them, and installing them" stages. I created a local action for those three steps. I didn't see any other obvious groups of steps that are shared between jobs.

I noticed that the unit tests job also fetches the base ref, but I believe that is entirely unnecessary since the unit tests don't run golangci-lint, unless I'm mistaken. So instead of grouping that in with the Debian dependency steps, I would just delete it during the clean-up task.

.github/workflows/spread-tests.yaml Show resolved Hide resolved
@maykathm maykathm force-pushed the SNAPDENG-34130-split-workflow-into-smaller-parts branch from 8c0f1cf to 2184efa Compare November 8, 2024 09:09
Copy link
Collaborator

@sergiocazzolato sergiocazzolato left a comment

Choose a reason for hiding this comment

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

Thanks for this change, I added 2 comments inline.

@@ -598,9 +188,20 @@ jobs:
verbose: true

spread:
uses: ./.github/workflows/spread-tests.yaml
needs: [unit-tests, snap-builds]
name: ${{ matrix.group }}
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we need a better name here, if could be "spread tests (${{ matrix.group }})"

@@ -11,7 +11,11 @@ concurrency:

jobs:
snap-builds:
runs-on: ubuntu-22.04
uses: ./.github/workflows/snap-builds.yaml
Copy link
Collaborator

Choose a reason for hiding this comment

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

thinking on keep this workflows directory organize, perhaps we could have a dir .github/workflows/jobs, and store there all the jobs we define.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unfortunately, github doesn't allow us to have subdirectories:

Creating a reusable workflow

Reusable workflows are YAML-formatted files, very similar to any other workflow file. As with other workflow files, you locate reusable workflows in the .github/workflows directory of a repository. Subdirectories of the workflows directory are not supported.

@maykathm maykathm force-pushed the SNAPDENG-34130-split-workflow-into-smaller-parts branch 6 times, most recently from d5095ab to 8edc8fd Compare November 8, 2024 15:26
@sergiocazzolato
Copy link
Collaborator

The only change I would like to see is the spread executions should be named something like this "spread ubuntu-xxxx"

Copy link
Collaborator

@sergiocazzolato sergiocazzolato left a comment

Choose a reason for hiding this comment

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

Excellent work, thanks

Copy link
Contributor

@zyga zyga left a comment

Choose a reason for hiding this comment

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

LGTM but have a look at some comments inline and please coordinate with branches landing from @sergiocazzolato

description: 'The go toolchain to use {default, FIPS}'
required: true
type: string
version:
Copy link
Contributor

Choose a reason for hiding this comment

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

In a follow-up let's rename this to variant or something else. The word version seems confusing as it's not the version string.

description: 'The spread system(s) to use (for possible values, check spread.yaml). If more than one, separate them with a space'
required: true
type: string
tests:
Copy link
Contributor

Choose a reason for hiding this comment

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

While we use this for testing, technically those are "tasks". Perhaps we could use that naming for consistency.

FAILED_TESTS="$(cat $FAILED_TESTS_FILE)"
if [ -n "$FAILED_TESTS" ]; then
echo "Failed tests to run: $FAILED_TESTS"
echo "FAILED_TESTS=$FAILED_TESTS" >> $GITHUB_ENV
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this not be unconditional? We can just emit an empty value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll take care of this in the cleanup task. Thanks for pointing it out!

if [ -n "$FAILED_TESTS" ]; then
RUN_TESTS="$FAILED_TESTS"
else
for SYSTEM in ${{ inputs.systems }}; do
Copy link
Contributor

Choose a reason for hiding this comment

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

CC @sergiocazzolato this is changed in the recently-approved PR from you. Please coordinate.

done

- name: Run spread tests
if: "!contains(github.event.pull_request.labels.*.name, 'Skip spread') && ( !startsWith(inputs.group, 'nested-') || contains(github.event.pull_request.labels.*.name, 'Run nested') )"
Copy link
Contributor

Choose a reason for hiding this comment

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

Ditto about filtering logic.

echo "Running command: $SPREAD $RUN_TESTS"
(set -o pipefail; $SPREAD -no-debug-output -logs spread-logs $RUN_TESTS | PYTHONDONTWRITEBYTECODE=1 ./tests/lib/external/snapd-testing-tools/utils/log-filter $FILTER_PARAMS | tee spread.log)

- name: Uploading spread logs
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
- name: Uploading spread logs
- name: Upload spread logs

Let's either use continuous or simple tense and stick to it across the jobs/workflows/actions.

# golang latest ensures things work on the edge
- name: Install the go snap
run: |
sudo snap install --classic --channel=${{ inputs.gochannel }} go
Copy link
Contributor

Choose a reason for hiding this comment

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

I wrote https://github.com/canonical/snapd-wsl-tests/tree/main/.github/actions/download-snap and https://github.com/canonical/snapd-wsl-tests/tree/main/.github/actions/install-offline-snap that we might want to use later on. One advantage is that they use GitHub cache so installation is very very fast, even if the store is slow or down completely. They'd have to be ported a little from powershell but the idea could stand.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice! I'll look into adding that in the cleanup task. That sounds great.

export SKIP_GOFMT=1
echo "Formatting checks will be skipped due to the use of Go version ${{ inputs.gochannel }}"
fi
sudo apt-get install -y python3-yamlordereddictloader
Copy link
Contributor

Choose a reason for hiding this comment

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

This is such a gotcha.

I'd love to move that part to go at some point.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

that would be great

fedora:*)
dnf install -y rpmdevtools
dnf install -y $(rpmspec -q --buildrequires "./packaging/$distroname/snapd.spec")
# TODO these are needed only by cmd/snap-seccomp unit tests, and
Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, thanks for reminding us about that. Let's do this soonish.

Copy link
Contributor

Choose a reason for hiding this comment

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

Well, I'm not sure we'll be able to fix it. It's apparently not easy to express such a dependency in the spec last time I attempted to address this

@maykathm maykathm force-pushed the SNAPDENG-34130-split-workflow-into-smaller-parts branch from 38bf9df to 5912d51 Compare November 12, 2024 17:31
@maykathm maykathm force-pushed the SNAPDENG-34130-split-workflow-into-smaller-parts branch from 5912d51 to c6bf903 Compare November 12, 2024 17:32
Copy link
Contributor

@bboozzoo bboozzoo left a comment

Choose a reason for hiding this comment

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

Thanks, looks great. I think I would only fix the newlines at this point and leave the rest for a followup PR.

.github/workflows/snap-builds.yaml Outdated Show resolved Hide resolved
.github/workflows/spread-tests.yaml Show resolved Hide resolved
# propagated; and we use a subshell as this option could trigger
# undesired changes elsewhere
echo "Running command: $SPREAD $RUN_TESTS"
(set -o pipefail; $SPREAD -no-debug-output -logs spread-logs $RUN_TESTS | PYTHONDONTWRITEBYTECODE=1 ./tests/lib/external/snapd-testing-tools/utils/log-filter $FILTER_PARAMS | tee spread.log)
Copy link
Contributor

Choose a reason for hiding this comment

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

since we're already modifying the code:

Suggested change
(set -o pipefail; $SPREAD -no-debug-output -logs spread-logs $RUN_TESTS | PYTHONDONTWRITEBYTECODE=1 ./tests/lib/external/snapd-testing-tools/utils/log-filter $FILTER_PARAMS | tee spread.log)
(
set -o pipefail
$SPREAD -no-debug-output -logs spread-logs $RUN_TESTS | \
PYTHONDONTWRITEBYTECODE=1 ./tests/lib/external/snapd-testing-tools/utils/log-filter $FILTER_PARAMS | \
tee spread.log
)

Copy link
Contributor

Choose a reason for hiding this comment

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

FWIW, not need to do this now, a followup PR is fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, I'll add this to the clean-up PR to follow

.github/workflows/spread-tests.yaml Outdated Show resolved Hide resolved
.github/workflows/static-checks.yaml Outdated Show resolved Hide resolved
fedora:*)
dnf install -y rpmdevtools
dnf install -y $(rpmspec -q --buildrequires "./packaging/$distroname/snapd.spec")
# TODO these are needed only by cmd/snap-seccomp unit tests, and
Copy link
Contributor

Choose a reason for hiding this comment

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

Well, I'm not sure we'll be able to fix it. It's apparently not easy to express such a dependency in the spec last time I attempted to address this

.github/workflows/unit-tests-cross-distro.yaml Outdated Show resolved Hide resolved
with:
# needed for git commit history
fetch-depth: 0
# NOTE: checkout the code in a fixed location, even for forks, as this
Copy link
Contributor

Choose a reason for hiding this comment

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

I suppose this is no longer an issue since we added go.mod support. Perhaps it's worth to check if we could simply use the project default location. FWIW, followup material.

.github/workflows/unit-tests.yaml Outdated Show resolved Hide resolved
@maykathm maykathm force-pushed the SNAPDENG-34130-split-workflow-into-smaller-parts branch from 2035734 to 519a3a1 Compare November 13, 2024 08:11
@maykathm maykathm force-pushed the SNAPDENG-34130-split-workflow-into-smaller-parts branch from 519a3a1 to 6e03b7c Compare November 13, 2024 08:55
@maykathm
Copy link
Contributor Author

The various failures throughout the spread tests are irrelevant to this PR.

@sergiocazzolato sergiocazzolato merged commit 9a71592 into canonical:master Nov 13, 2024
49 of 57 checks passed
@maykathm maykathm deleted the SNAPDENG-34130-split-workflow-into-smaller-parts branch November 13, 2024 15:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants