GitHub Action to formats all XML files found in a pull request with the
xmlformat
tool.
This GitHub Action takes care of:
- Installs the
xmlformat
package. - Finds the
xmlformat
script. For some distributions, it is available asxmlformat
,xmlformat.rb
orxmlformat.pl
. It will find the script in the mentioned order. - Investigates what files are integrated in the commit.
Optionally, it lets you set additional parameters:
- Set a configuration file. If it's a remote address, it will download the config file automatically.
- Define a list of excluded files.
- Define a list of allowed file extensions.
- Define a default Git identity.
- Commit the changed XML files.
The GitHub Action does not push the changed XML files automatically. You have to do it after you have formatted the files (see Pushing reformatted XML files.)
This GitHub Action consists of composite run steps. Used commands are:
bash
curl
git
jq
xmlformat
Except for xmlformat
, all commands are already available
in the default image (Ubuntu).
If you use any other image, make sure to have these commands available.
This GH Action is only useful for real commits, not tags. As such, it is needed to skip any runs when you've created tags. Use these lines:
jobs:
reformat-xml:
# True for any branches, but is skipped for tags
# For tags it would be 'refs/tags/'
if: startsWith(github.ref, 'refs/heads/')
To avoid shallow copies of your checkout, you need to get all
commits from your history.
When checking out your repository with actions/checkout
,
use the option fetch-depth
and set it to zero:
- uses: actions/checkout@v2
with:
# Number of commits to fetch.
# 0 indicates all history for all branches and tags.
# This is absolutely needed for this action,
# otherwise it won't work!
fetch-depth: 0
Important: If you forget the fetch-depth
option, the xml-format-action
won't find any files at all!
Another recommendation (although it's not a requirement) is to use the
on.push.paths
key.
This key could be helpful if you are only interested to enable this
action for specific paths or files:
---
on:
push:
paths:
# Only active this GH Action when these files are changed:
- "a/*.xml"
- "b/*.xml"
Name | Required? | Type | Default | Explanation |
---|---|---|---|---|
commit |
no | bool1 | true | flag: should the formatted files committed? |
commit-message |
no | string | "..." | commit message for the reformatting step |
config |
no | file/URL2 | n/a | config file for the xmlformat script |
extensions |
no | string/ML3 | xml |
file extensions for XML files (without dots or globs) |
exclude-files |
no | string/ML3 | n/a | Excluded XML files from reformatting |
repo-token |
yes | string | n/a | The GitHub token, usually secrets.GITHUB_TOKEN . Needed to access the repo. |
xmlformat-variant |
no | string | perl | The package variant to install (perl or ruby) |
xmlformat-use-tag |
no | string | n/a | Use the given tag from xmlformat upstream GH repository |
[1]: boolean value, use true
(also
allowed is 1
or yes
).
[2]: if you pass a GitHub URL, it's recommended to
use https://raw.githubusercontent.com/OWNER/PROJECT/<PATH>
as URL.
However, it also works for GitHub URLs like
https://github.com/OWNER/PROJECT/raw/<PATH>
.
[3]: multi line input with the pipe symbol (|
)
or as a string. Each part is separated by one or more spaces.
Name | Type | Explanation |
---|---|---|
xmlfound |
bool | Does the commit contains some XML files and were they reformatted? |
This workflow is only activated, when some XML files inside
the xml/
and the root paths have been changed (using the
on.push.paths
key):
# Add .github/workflows/reformat-xml.yml
on:
push:
paths:
- "xml/*.xml"
- "*.xml"
jobs:
reformat-xml:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
# Number of commits to fetch. See above.
fetch-depth: 0
- name: Format XML
uses: tomschr/xml-format-action@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
In most cases, the default formatting is not what you want.
If you already have a configuration file (either in your
current repository or somewhere else) you can provide this.
Use the config
input:
# Add .github/workflows/reformat-xml-config.yml
on:
push:
paths:
# Add more paths to this list:
- "xml/*.xml"
jobs:
reformat-xml:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Format XML
uses: tomschr/xml-format-action@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
config: doc/docbook-xmlformat.conf
It's also possible to use a URL for the config file. For example:
- name: Format XML from remote URL
uses: tomschr/xml-format-action@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
config: https://raw.githubusercontent.com/openSUSE/daps/main/etc/docbook-xmlformat.conf
In this case, the remote config file is downloaded and saved
outside the checked out repository (in the /tmp
directory).
Sometimes you have configuration files which happen to end
with the same file extension (Emacs has schemas.xml
). If
you want to exclude such files from reformatting, use the
key exclude-files
:
# Add .github/workflows/reformat-xml-exclude-files.yml
on:
push:
paths:
# Add more paths to this list:
- "xml/*.xml"
jobs:
reformat-xml:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Format XML
uses: tomschr/xml-format-action@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
exclude-files: "xml/schemas.xml"
If you want to exclude more than one file, use the pipe (|
)
symbol:
- name: Format XML
uses: tomschr/xml-format-action@v1
with:
exclude-files: |
xml/foo.xml
xml/bar.xml
In some cases you have your XML files which does not end up with .xml
.
For example, SVG (.svg
) or MathML (.mml
) files.
Use the extensions
key to add them:
# Add .github/workflows/reformat-xml-extensions.yml
on:
push:
paths:
# Add more paths to this list:
- "xml/*.xml"
jobs:
reformat-xml:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Format XML
uses: tomschr/xml-format-action@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
extensions: "mml"
You can also use the pipe (|
) symbol to add more than
one file extension:
- name: Format XML, SVG, and MathML
uses: tomschr/xml-format-action@v1
with:
extension: |
xml
svg
mml
If you prefer a different commit message, use the key commit-message
:
# Add .github/workflows/reformat-xml-extensions.yml
on:
push:
paths:
# Add more paths to this list:
- "xml/*.xml"
jobs:
reformat-xml:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Format XML
uses: tomschr/xml-format-action@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "Reformatted by xml-format-action"
If something goes wrong, you can introduce the following step into your workflow:
- name: Dump GitHub Context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "${GITHUB_CONTEXT}"
This converts the GitHub context into JSON and outputs it in your action.
The GitHub Action reformats the XML files (excluding the exclusion list) and commits them. However, it does not push any files.
If you want to push reformatted XML files to your GitHub repository, use the actions-go/push action. Or, if you want to do it manually, use these steps in your workflow file:
- name: Format DocBook XML
id: dbxml
uses: tomschr/xml-format-action@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
# use whatever you need
- name: Push
if: ${{ steps.dbxml.outputs.xmlfound }}
run: |
# Remove any refs/heads/ parts:
BRANCH="${GITHUB_REF#refs/heads/}"
URL="https://${{github.actor}}:${{secrets.GITHUB_TOKEN}}@github.com/${{github.repository}}.git"
git push "$URL" "$BRANCH"
The push step only pushes files if the previous step (Format DocBook XML
with id=dbxml
) contained
files which are detected as XML and where changed.