Package: gawd
gawd - GitHub Actions Workflow Differgawdstands forGitHubActionsWorkflowDiffer.
It is a Python library and command-line tool that computes all changes (i.e., diffs) between two GitHub Actions workflow files.
Given a pair of workflow files as input, and taking the specific syntax of GitHub Actions into account,gawdreports on the items that were added and removed, as well on items that were moved, renamed or changed based on their similarity.Installationgawdcan be used in two ways: as a command-line tool and as a reusable Python library.You can usepip install gawdto install the latest available version fromPyPI.
Pre-releases are available from themainbranch onGitHuband can be installed withpip install git+https://github.com/pooya-rostami/gawd.UsageAs a command-line toolAfter installation, thegawdcommand-line tool should be available in your shell.
Otherwise, you can call it usingpython -m gawd.usage: gawd [-h] [--threshold X] [--position-weight X] [--job-name-weight X]
            [--short] [--json] [--verbose]
            first second

gawd is an open source GitHub Actions Workflow Differencing tool that is aware
of the specific workflow syntax of GitHub Actions workflows. Given a pair of
workflow files as input, the tool reports on the items that were added and
removed, as well on items that were moved, renamed or changed based on their
similarity.

positional arguments:
  first                 path to first workflow (YAML) file
  second                path to second workflow (YAML) file

optional arguments:
  -h, --help            show this help message and exit
  --threshold X, -t X   ranged from 0 to 1, distance threshold to map items,
                        value closer to 1 favours "changed", value closer to 0
                        favours "added" and "removed" (default is 0.5)
  --position-weight X, -p X
                        ranged from 0 to 1, weight of item positions when
                        comparing sequences (default is 0.2)
  --job-name-weight X, -j X
                        ranged from 0 to 1, weight of job names when comparing
                        jobs (default is 0.2)
  --short, -s           limit the output of values to a few characters
  --json                output in json
  --verbose             output in more detailExamples:Let us take the changes made to the workflow file "main.yml" inthis commitas an example.--shortCondensed output ofgawdwhen applied to compute the changes:>>>gawdold_main.yamlnew_main.yaml--shortchangedjobs.build-linux-clangpdb-gcc5.steps[1].runfrom"'sudo apt-get update (...) UB_PATH\n'"to"'sudo apt-get update (...) UB_PATH\n'"renamedjobs.build-linux-clang38tojobs.build-linux-clangdwarfchangedjobs.build-linux-clang38.namefrom"'Build Linux CLANG38'"to"'Build Linux CLANGDWARF'"changedjobs.build-linux-clang38.env.TOOLCHAINSfrom"'CLANG38'"to"'CLANGDWARF'"changedjobs.build-linux-clang38.steps[6].with.namefrom"'Linux CLANG38 Artifacts'"to"'Linux CLANGDWARF Artifacts'"--jsonTo output the results in JSON format:>>>gawdold_main.yamlnew_main.yaml--short--json[{"type":"changed","old":{"path":"jobs.build-linux-clangpdb-gcc5.steps[1].run","value":"'sudo apt-get update (...) UB_PATH\\n'"},"new":{"path":"jobs.build-linux-clangpdb-gcc5.steps[1].run","value":"'sudo apt-get update (...) UB_PATH\\n'"}},{"type":"renamed","old":{"path":"jobs.build-linux-clang38","value":"{'name': 'Build Linu (...) *.zip'}}]}"},"new":{"path":"jobs.build-linux-clangdwarf","value":"{'name': 'Build Linu (...) *.zip'}}]}"}},{"type":"changed","old":{"path":"jobs.build-linux-clang38.name","value":"'Build Linux CLANG38'"},"new":{"path":"jobs.build-linux-clangdwarf.name","value":"'Build Linux CLANGDWARF'"}},{"type":"changed","old":{"path":"jobs.build-linux-clang38.env.TOOLCHAINS","value":"'CLANG38'"},"new":{"path":"jobs.build-linux-clangdwarf.env.TOOLCHAINS","value":"'CLANGDWARF'"}},{"type":"changed","old":{"path":"jobs.build-linux-clang38.steps[6].with.name","value":"'Linux CLANG38 Artifacts'"},"new":{"path":"jobs.build-linux-clangdwarf.steps[6].with.name","value":"'Linux CLANGDWARF Artifacts'"}}]--thresholdA value between 0 and 1 representing the sensitivity ofgawdin identifying changes. A higher threshold results in more instances of 'changed' or 'renamed', while a lower threshold favours 'added' or 'removed':>>>gawdold_main.yamlnew_main.yaml--short--threshold0.1removedjobs.build-linux-clangpdb-gcc5.steps[1]with{'name':'Install De (...) B_PATH\n'}addedjobs.build-linux-clangpdb-gcc5.steps[1]with{'name':'Install De (...) B_PATH\n'}removedjobs.build-linux-clang38with{'name':'Build Linu (...) *.zip'}}]}addedjobs.build-linux-clangdwarfwith{'name':'Build Linu (...) *.zip'}}]}As an importable librarygawdcomes with two functions to compare workflow files, namelydiff_workflow_filesanddiff_workflows.
The former accepts the paths to two workflow files, loads them and returns the output ofdiff_workflows.
The latter accepts two workflows as Python dictionaries (e.g., loaded withruamel.yaml) and returns a list of 5-tuples(kind, old_path, old_value, new_path, new_value).Thekindcomponent is one ofadded, removed, changed, moved, renamedand indicates the kind of change.old_pathandnew_pathcorrespond to a dotted notation indicating where the change occurred, whileold_valueandnew_valuecorrespond to the previous and new values, respectively.
Notice thatold_pathandold_valueare set toNonein case of an "added" change, andnew_pathandold_pathareNonein case of a "removed" change.Similarly to the extra parameters that can be provided to the CLI tool, thegawdmodule exposesTHRESHOLD,POSITION_WEIGHTandJOB_NAME_WEIGHT.The following example shows the output of the imported library version ofgawdfor the changes made to the workflow filemain.ymlinthis commit.>>>fromgawdimportdiff_workflow_files>>>old_workflow_path=...>>>new_workflow_path=...>>>diff_workflow_files(old_workflow_path,new_workflow_path)[('changed','jobs.build-linux-clangpdb-gcc5.steps[1].run','sudo apt-get update\nsudo apt-get install nasm ...','jobs.build-linux-clangpdb-gcc5.steps[1].run','sudo apt-get update\nsudo apt-get install nasm ...'),('renamed','jobs.build-linux-clang38',{'name':'Build Linux CLANG38',...},'jobs.build-linux-clangdwarf',{'name':'Build Linux CLANGDWARF',...}),('changed','jobs.build-linux-clang38.name','Build Linux CLANG38','jobs.build-linux-clangdwarf.name','Build Linux CLANGDWARF'),('changed','jobs.build-linux-clang38.env.TOOLCHAINS','CLANG38','jobs.build-linux-clangdwarf.env.TOOLCHAINS','CLANGDWARF'),('changed','jobs.build-linux-clang38.steps[6].with.name','Linux CLANG38 Artifacts','jobs.build-linux-clangdwarf.steps[6].with.name','Linux CLANGDWARF Artifacts')]ContributionsContributions are very welcome!
Feel free to report bugs or suggest new features using GitHub issues and/or pull requests.LicenseThis tool is distributed underGNU Lesser General Public License v3.CitingYou can refer to the scientific publication describing this tool using@inproceedings{gawd2024MSR,
  author = {{Rostami Mazrae}, Pooya and Decan, Alexandre and Mens, Tom},
  title = {gawd: A Differencing Tool for GitHub Actions Workflows},
  booktitle = {International Conference on Mining Software Repositories - Data and Tools Showcase Track},
  year = 2024
}You can also refer to this tool directly using:@software{gawd2023,
  author = {{Rostami Mazrae}, Pooya and Decan, Alexandre},
  title = {gawd: GitHub Actions Workflow Differ},
  url = {https://github.com/pooya-rostami/gawd},
  year = 2023,
  institute = {Software Engineering Lab at University of Mons, Belgium}
}