Don't bother with your localisation when you make a change to an original file, let this Action automatically backtrack changes and instruct your translators for reflected changes on translation files through Github Issues or Github Projects.
Currently, the Update Tracker Action purpose is to solely serve the BSMG Wiki, tracking updated English pages and notifying in issues/projects. As such, templates are specifically customized for a Wiki using vuepress i18n. It is currently being reviewed to work in more places and localisation structures.
The Update Tracker for Translations has 3 main features:
- Backtracking
- Analyse commit history to provide status for translation files according to their corresponding original files.
- Auto Generation
- Automatically create stubs or copy original for missing translation files, or remove orphan translation files. Either proposed in mergeable dedicated branch or directly to your main branch.
- Instructing
- Instruct every changes in Github Issues and/or Projects, according to custom templates contextualized for each backtracked translation file.
Note that it does not parse file contents nor automatically translate. See Assumptions .
Tracked translation files can have one of these statuses:
- To Create
- The translation file doesn't exist where a corresponding original file does.
- To Initialize
- The translation file exists but does not contain translation yet.
- To Update
- The translation file was translated but the original file was edited thereafter.
- Up-To-Date
- The translation file was edited after or the same as its corresponding original file.
- Orphan
- The translation file exists but doesn't have a corresponding original file.
For the system to work efficiently, these assumptions are made and should be respected:
- every translation folders have the same tree view and filenames as the original folder
- when a translation file is edited, the translation is always based on the most recent original file.
- New Orphan status when a translation file has no affiliated original file
- More control on templates: set them directly in the workflow file or in files
- Can now copy files (like images or videos)
- Control which files to track, and then to generate and instruct using glob and fnmatch patterns
- New feature to generate changes to another branch and making a pull request to merge to initial branch
- Better documentation I guess
- Code structure reviewed again along with better argument parsing
- WARNING: a lot of inputs were changed and new ones were added, check inputs below
- Github Projects is supported through input
update-projects
. - Issues can now be enabled and disabled through input
update-issues
. - Script much more stable and adaptable.
- WARNING:
translation-paths
was removed, because paths must now be given with corresponding language tags as described in new inputtranslations
.
- Update Tracker now automatically creates stub files when missing, with the correct header. Can be enabled or disabled in
auto-create
input.
- New comprehensive Frontmatter header
translation-done: false
to read from markdown or other Frontmatter compatible translation file automatically sets the status to TBI (To Be Initialized).
Example at the very beginning of a dummy file example.md
:
---
translation-done: false
---
Pre-requisite is a checked-out git repository set up on the active branch you want to track (use checkout).
Then use this job in your workflow file:
- uses: Awagi/wiki-update-tracker@v1.8
with:
# The python script log level, either CRITICAL, ERROR, WARNING, INFO, DEBUG or NOTSET.
# Change it for more or less verbosity in the Action.
#
# Not required. Default: 'INFO'.
log-level: 'INFO'
# 1) TRACKER
# The local path of the checked-out git repository, make sure you checkout on the desired branch.
#
# REQUIRED.
repo-path: '.'
# Path to the directory containing original files, relative to repo-path.
#
# REQUIRED.
original: 'docs'
# Paths to the directories containing translation files, relative to repo-path, along with their associated language tag.
# Language tag must respect RFC5646.
#
# REQUIRED.
translations: |-
fr:docs/fr
cs:docs/cs
# Glob patterns matching files to track within original path and translation paths.
# You may want to keep track of only text files like .md or so.
# These filters are used in original path and in translations path to check which files exist and their corresponding original/translation.
# Note: files or directories starting with a '.' won't be included as it is a tradition from glob. If you need so, you should explicitly include these in filters.
# More info about glob patterns: https://docs.python.org/3.6/library/glob.html
#
# Not required. Default: '**/*'.
filters: |-
**/*.md
**/*.png
# Glob patterns matching files to ignore when parsing original files, relative to repo-path.
# If a translation or original file matches a filter from the above filters, it will still be ignored if matching one of these patterns.
# More info about glob patterns: https://docs.python.org/3.6/library/glob.html
#
# Not required. Default: ''.
ignores: |-
**/README.md
# 2) GENERATION
# Automatically create stubs for To Create translation files matching one of the given fnmatch patterns, with content defined by stub-template.
# Checked-out repository must have be able to push to destination branch (defined by gen-branch parameter).
# More info about fnmatch patterns: https://docs.python.org/3.6/library/fnmatch.html
#
# Not required. Default: ''.
gen-stubs: |-
*.md
# The commit message when generating stub files.
#
# Not required. Default: ':tada: Created stub translation files'.
stub-commit: ':tada: Created stub translation files'
# Template file defining the content of generated stub files. This template parameter requires a file path containing the actual template.
# More info about templates in the section below.
#
# This template will be provided a To Create translation track context + special stub arguments.
#
# Not required. Default: ''.
stub-template: '.github/update-tracker/stub-template.md'
# Automatically copy original files to To Create translation files matching one of the given fnmatch patterns.
# Checked-out repository must have be able to push to destination branch (defined by gen-branch parameter).
# More info about fnmatch patterns: https://docs.python.org/3.6/library/fnmatch.html
#
# Not required. Default: ''.
gen-copy: |-
*.png
# The commit message when generating file copies.
#
# Not required. Default: ':tada: Copied original to translation files'.
copy-commit: ':tada: Copied original to translation files'
# The branch where files will be pushed when auto generating changes.
# If it is not set, files will be committed to the checked-out repository active branch.
# The actual destination branch, whether it is another branch or the active checked-out branch, must exist and be not branch-protected.
#
# Note that if the destination branch is another branch than the active branch, it will always be rebased on the active branch HEAD when the Action triggers and new files are generated.
# This means you may lose any changes made to this specific branch, you shouldn't use it for other purposes.
#
# Not required. Default: ''.
gen-branch: 'genbranch'
# 3) INSTRUCTING
# The GitHub repository where you want to instruct tracked and generated changes, in the form "Author/repo".
#
# Not required. Default: '${{ github.repository }}'.
repository: '${{ github.repository }}'
# The authorization token to instruct Issues, Projects and Pull requests.
# You should make sure the GitHub App this token gives access to has enough permissions to update what you set.
#
# Also, it is recommended to use your own installation of a GitHub App instead of GitHub Actions provided to strictly define the least permission required.
# Building GitHub Apps: https://developer.github.com/apps/building-github-apps/
#
# Not required. Default: '${{ github.token }}'.
token: '${{ github.token }}'
# Request merging gen-branch (if the parameter is set and if changes were applied) to checked-out repository active branch through a Pull Request.
# The GitHub App token requires read/write access to Pull Requests.
#
# Beware: if repository is defined as another repository than the git repo were changes were pushed, requesting merge as Pull Request will fail.
#
# Not required. Default: 'false'.
request-merge: 'true'
# Instruct translators on translation files matching one of the given fnmatch patterns through GitHub Issues.
# The GitHub App token requires read/write access to Issues.
#
# Not required. Default: ''
instruct-issues: |-
*.md
# The label name to manage issues, issues not labelled with it won't be processed.
#
# Not required. Default: 'translation-tracker'.
issue-label: 'translation-tracker'
# The issue title template.
# As the resulting issue title must be unique, the template should include {t.translation.path}.
# More info about templates in the section below.
#
# This template will be provided any translation track context regardless of status + special GitHub arguments.
#
# Not required. Default: 'Translation file: {t.translation.path}'.
issue-title-template: 'Translation file: {t.translation.path}'
# The issue body template file for To Create translation files. This template parameter requires a file path containing the actual template.
# More info about templates in the section below.
# If not set, To Initialize translation tracks won't be instructed in Issues.
#
# This template will be provided a To Create translation track context + special GitHub arguments.
#
# Not required. Default: ''.
issue-create-template: .github/update-tracker/issue-create-template.md
# The issue body template file for To Initialize translation files. This template parameter requires a file path containing the actual template.
# More info about templates in the section below.
# If not set, To Initialize translation tracks won't be instructed in Issues.
#
# This template will be provided a To Initialize translation track context + special GitHub arguments.
#
# Not required. Default: ''.
issue-initialize-template: .github/update-tracker/issue-init-template.md
# The issue body template file for To Update translation files. This template parameter requires a file path containing the actual template.
# More info about templates in the section below.
# If not set, To Update translation tracks won't be instructed in Issues.
#
# This template will be provided a To Update translation track context + special GitHub arguments.
#
# Not required. Default: ''.
issue-update-template: .github/update-tracker/issue-update-template.md
# The issue body template file for Up-To-Date translation files. This template parameter requires a file path containing the actual template.
# More info about templates in the section below.
# If not set, Up-To-Date translation tracks won't be instructed in Issues.
#
# This template will be provided a Up-To-Date translation track context + special GitHub arguments.
#
# Not required. Default: ''.
issue-uptodate-template: .github/update-tracker/issue-utd-template.md
# The issue body template file for Orphan translation files. This template parameter requires a file path containing the actual template.
# More info about templates in the section below.
# If not set, Orphan translation tracks won't be instructed in Issues.
#
# This template will be provided an Orphan translation track context + special GitHub arguments.
#
# Not required. Default: ''.
issue-orphan-template: .github/update-tracker/issue-orphan-template.md
# Instruct translators on translation files matching one of the given fnmatch patterns through GitHub Projects.
# The Github App token requires read/write access to Projects.
#
# Not required. Default: ''.
instruct-projects: |-
*.md
# The project name template.
# More info about templates in the section below.
#
# This template will be provided any translation track context regardless of status + special GitHub arguments.
#
# Not required. Default: '{t.translation.language} Update Tracker'.
project-title-template: '{t.translation.language} Update Tracker'
# The project description template. Only used when the project is created.
# More info about templates in the section below.
#
# This template will be provided any translation track context regardless of status + special GitHub arguments.
#
# Not required. Default: '{t.translation.language} translation effort.'.
project-description-template: '{t.translation.language} translation effort.'
# The column template in project to include To Create translation file cards. This template parameter requires a file path containing the actual template.
# More info about templates in the section below.
# If not set, To Create translation tracks won't be instructed in Projects.
#
# This template will be provided a To Create translation track context + special GitHub arguments.
#
# Not required. Default: 'To Initialize'.
project-column-create-template: 'To Initialize'
# The column template in project to include To Initialize translation file cards. This template parameter requires a file path containing the actual template.
# More info about templates in the section below.
# If not set, To Initialize translation tracks won't be instructed in Projects.
#
# This template will be provided a To Initialize translation track context + special GitHub arguments.
#
# Not required. Default: 'To Initialize'.
project-column-initialize-template: 'To Initialize'
# The column template in project to include To Update translation file cards. This template parameter requires a file path containing the actual template.
# More info about templates in the section below.
# If not set, To Update translation tracks won't be instructed in Projects.
#
# This template will be provided a To Update translation track context + special GitHub arguments.
#
# Not required. Default: 'To Update'.
project-column-update-template: 'To Update'
# The column template in project to include Up-To-Date translation file cards. This template parameter requires a file path containing the actual template.
# More info about templates in the section below.
# If not set, Up-To-Date translation tracks won't be instructed in Projects.
#
# This template will be provided a Up-To-Date translation track context + special GitHub arguments.
#
# Not required. Default: 'Up-To-Date'.
project-column-uptodate-template: 'Up-To-Date'
# The column template in project to include Orphan translation file cards. This template parameter requires a file path containing the actual template.
# More info about templates in the section below.
# If not set, Orphan translation tracks won't be instructed in Projects.
#
# This template will be provided an Orphan translation track context + special GitHub arguments.
#
# Not required. Default: 'Orphans'.
project-column-orphan-template: 'Orphans'
# The card template file in project column for To Create translation files. This template parameter requires a file path containing the actual template.
# More info about templates in the section below.
# If not set, To Create translation tracks won't be instructed in Projects.
# Also, a note in a card is limited to 1024 characters.
#
# This template will be provided a To Create translation track context + special GitHub arguments.
#
# Not required. Default: ''.
project-card-create-template: .github/update-tracker/card-create-template.md
# The card template file in project column for To Initialize translation files. This template parameter requires a file path containing the actual template.
# More info about templates in the section below.
# If not set, To Initialize translation tracks won't be instructed in Projects.
# Also, a note in a card is limited to 1024 characters.
#
# This template will be provided a To Initialize translation track context + special GitHub arguments.
#
# Not required. Default: ''.
project-card-initialize-template: .github/update-tracker/card-init-template.md
# The card template file in project column for To Update translation files. This template parameter requires a file path containing the actual template.
# More info about templates in the section below.
# If not set, To Update translation tracks won't be instructed in Projects.
# Also, a note in a card is limited to 1024 characters.
#
# This template will be provided a To Update translation track context + special GitHub arguments.
#
# Not required. Default: ''.
project-card-update-template: .github/update-tracker/card-update-template.md
# The card template file in project column for Up-To-Date translation files. This template parameter requires a file path containing the actual template.
# More info about templates in the section below.
# If not set, Up-To-Date translation tracks won't be instructed in Projects.
# Also, a note in a card is limited to 1024 characters.
#
# This template will be provided a Up-To-Date translation track context + special GitHub arguments.
#
# Not required. Default: ''.
project-card-uptodate-template: .github/update-tracker/card-utd-template.md
# The card template file in project column for Orphan translation files. This template parameter requires a file path containing the actual template.
# More info about templates in the section below.
# If not set, Orphan translation tracks won't be instructed in Projects.
# Also, a note in a card is limited to 1024 characters.
#
# This template will be provided an Orphan translation track context + special GitHub arguments.
#
# Not required. Default: ''.
project-card-orphan-template: .github/update-tracker/card-orphan-template.md
You might also find useful these examples.
Templates allow you to define your own custom content when generating stub files or instructing issues and projects.
A template context is given in every template inputs: you know for which status the template is going to be formatted, or if it is formatted regardless of the status. Knowing so, you can create your template using provided arguments.
Arguments must be included in the template as a Python format tag, surrounded with curly brackets, like {arg}
.
A t
argument is always given in templates, representing a TranslationTrack
and holding values described in tracks
output. Also you can find special arguments in every specific template.
If the argument doesn't exist in a given context, it will result in an error stopping the Action.
Example:
issue-title-template: "{t.translation.language} translation: {t.translation.path}"
This would result in something like "French translation: wiki/fr/README.md"
.
When updating Issues or Projects, special arguments are provided in addition to t
.
Argument | Description | To Create | To Initialize | To Update | Up-To-Date | Orphan |
---|---|---|---|---|---|---|
original_url |
Github URL to original file (using commit rev) | X | X | X | X | |
raw_original_url |
Github URL to raw original file (using commit rev) | X | X | X | X | |
translation_url |
Github URL to translation file (using branch rev) | X | X | X | X | |
raw_translation_url |
Github URL to raw translation file (using commit rev) | X | X | X | X | |
base_original_url |
Github URL to base original file (using commit rev) | X | ||||
raw_base_original_url |
Github URL to raw base original file (using commit rev) | X | ||||
compare_url |
Github URL to Github comparison (using base_original and original commit rev) | X |
Example for a translation file to update:
Check what changed in `{t.original.path}` [**here**]({compare_url}).
Note that these new keys are provided outside of the t
instance of TranslationTrack
.
When generating stub files, a special argument is provided in addition to t
: translation_to_original_path
. It's the relative path from the translation file parent directory to the original file.
JSON representation of tracked translation and original files, as a list of TranslationTrack
.
A TranslationTrack
object contains:
Status | Key | Value type | Description |
---|---|---|---|
All | translation |
TranslationGitFile object |
Tracked translation file. |
All | original |
GitFile object |
Matching original file. |
All | status |
string | Either "To Create" , "To Initialize" , "To Update" , "Up-To-Date" , "Orphan" . |
"To Create" |
missing_lines |
integer | Number of missing lines in translation file, i.e actual number of lines in original file. |
"To Initialize" |
missing_lines |
integer | Number of missing lines in translation file, i.e actual number of lines in original file. |
"To Update" |
base_original |
GitFile object |
Base original file used to update most recent translation file. |
"To Update" |
patch |
GitPatch object |
Patch with changes from base original file to original file, instructing required update. |
"To Update" |
to_rename |
boolean | Indicates whether the translation file has to be renamed like the new original filename, or not. |
"Orphan" |
deleted |
boolean | Indicates whether the original file was deleted, or not (i.e it never existed). |
"Orphan" |
surplus_lines |
integer | Number of lines in excess, i.e actual number of lines in translation file. |
Note that some data appears only for a specific status. When requesting a value from this object, say a template, be sure to understand the context. Should it trigger for every tracks regardless of the status, don't use specific values.
A GitFile
object contains:
Key | Value type | Description |
---|---|---|
path |
string | Path to the file, relative to the git repository. |
filename |
string | Name of the file. |
directory |
string | File parent directory, relative to the git repository (might be "."). |
no_trace |
boolean | Indicates whether the file doesn't exist in git commit history, or it does. |
commit |
string or null | Sha-1 (40 hexadecimal characters) of the most recent commit modifying the file, null if no_trace is true. |
new_file |
boolean | Indicates whether the file is a new file in commit, or not. |
copied_file |
boolean | Indicates whether the file was copied in commit, or not. |
renamed_file |
boolean | Indicates whether the file was renamed in commit, or not. |
rename_from |
string or null | Path of the old filename if it was renamed. |
rename_to |
string or null | Path of the new filename if it was renamed. |
deleted_file |
boolean | Indicates whether the file was deleted in commit, or not. |
A TranslationGitFile
object contains every items of a GitFile
object, plus:
Key | Value type | Description |
---|---|---|
lang_tag |
string | Language tag, as of RFC5646 |
language |
string | Language, as of RFC5646 |
A GitPatch
object contains:
Key | Value type | Description |
---|---|---|
diff |
string | Literal git diff indicated what was changed. |
additions |
integer | Number of lines added. |
deletions |
integer | Number of lines deleted. |
changes |
integer | Total number of lines changed. |
Example:
[
{
"translation": {
"path": "wiki/zh/grips-and-tricks.md",
"no_trace": false,
"commit": "4ce6ebd661d3a0ce1b0e07212f092e73b5c7c252",
"new_file": false,
"copied_file": false,
"renamed_file": false,
"rename_from": null,
"rename_to": null,
"deleted_file": false,
"lang_tag": "zh",
"language": "Chinese"
},
"original": {
"path": "wiki/grips-and-tricks.md",
"no_trace": false,
"commit": "d6fb43c9fa56999ce9339bc2bdaa95b7dcbc0964",
"new_file": false,
"copied_file": false,
"renamed_file": false,
"rename_from": null,
"rename_to": null,
"deleted_file": true
},
"status": "Orphan",
"deleted": true,
"surplus_lines": 0
}
]
You can use this output in other actions in your workflow using the fromJSON expression.
Comma-separated list containing open issue numbers (when a file requires updating, creation or initialization).
Example: 65,67,70
Let's imagine a Vuepress tree view as described in Vuepress site level i18n config:
docs
├─ README.md
├─ foo.md
├─ nested
│ └─ README.md
└─ zh
│ ├─ README.md
│ ├─ foo.md
│ └─ nested
│ └─ README.md
└─ fr
├─ README.md
├─ foo.md
└─ nested
└─ README.md
Original pages are located in docs
, while translation pages are reflected in docs/zh
and docs/fr
.
To keep track of discrepancies between original pages in docs
and translation pages in docs/zh
and docs/fr
, see the example workflow file using this action.
Documentation can be found in Python modules within src/
.
This project assets (source code, documentation and examples) are published under the MIT License.