Changeset - 1aec204a7286
[Not reviewed]
0 1 0
Branko Majic (branko) - 2 years ago 2022-08-21 14:06:31
branko@majic.rs
[factorio_development.sh] Added command for releasing mods:

- Accepts mod version for the release.
- Tries to ease the process as much as possible, including updating
version numbers, tagging, and switching back to development
version.
- Include some comments in generated build configuration file.
1 file changed with 203 insertions and 1 deletions:
0 comments (0 inline, 0 general) First comment
games/factorio_development.sh
Show inline comments
 
@@ -19,22 +19,23 @@
 
#
 

	
 
# Treat unset variables as errors.
 
set -u
 

	
 
PROGRAM="factorio_development.sh"
 
VERSION="0.0.2"
 
VERSION="0.0.3"
 

	
 
function usage() {
 
    cat <<EOF
 
$PROGRAM $VERSION, helper tool for development of Factorio mods
 

	
 
Usage:
 

	
 
  $PROGRAM [OPTIONS] init MOD_DIRECTORY_PATH
 
  $PROGRAM [OPTIONS] build [MOD_DIRECTORY_PATH]
 
  $PROGRAM [OPTIONS] release [MOD_DIRECTORY_PATH]
 

	
 
EOF
 
}
 

	
 
function short_help() {
 
    cat <<EOF
 
@@ -112,12 +113,50 @@ build [MOD_DIRECTORY_PATH]
 
  By default, the build command includes all files in the release
 
  archive - even when separate directory for mod sources is
 
  used. Files can be excluded from the archive via "ignore_paths"
 
  option in build configuration file (build.cfg).
 

	
 

	
 
release MOD_VERSION [MOD_DIRECTORY_PATH]
 

	
 
  Arguments:
 

	
 
    MOD_VERSION (version to release)
 
    MOD_DIRECTORY_PATH (path to base directory)
 

	
 
  Builds release of a mod. Expects (optional) path to mod base
 
  directory. Default is to use working directory as mod directory
 
  path.
 

	
 
  Release process will:
 

	
 
  - Create new branch based on passed-in version.
 
  - Replace development version in info.json and changelog.txt with
 
    passed-in release version, and commit those changes.
 
  - Build the release.
 
  - Create annotated tag.
 
  - Switch back to development version in info.json and changelog.txt
 
    and commit those changes.
 

	
 
  When committing the changes, user will be prompted to modify the
 
  pre-defined commit message (if so desired).
 

	
 
  After this has been taken care of, the following manual steps are
 
  required:
 

	
 
  - Merge the release branch into main branch.
 
  - Push the changes and tags to repository origin.
 
  - Upload the release to mods portal.
 

	
 
  The release process can be configured to use a prefix for version
 
  tags using the git_version_tag_prefix option in the build
 
  configuration file (build.cfg). This can be used to, for example,
 
  have the tags created as "release/1.0.0" or "v1.0.0" instead of
 
  default "1.0.0".
 

	
 

	
 
$PROGRAM accepts the following options:
 

	
 
    -q
 
        Quiet mode.
 
    -d
 
        Enable debug mode.
 
@@ -264,16 +303,22 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 
SOFTWARE.
 
EOF
 

	
 
    cat <<EOF > "$base_dir/build.cfg"
 
# -*- mode: sh-mode; sh-shell: bash -*-
 

	
 
# Specify list of paths to exclude from the built release archives.
 
ignore_paths=(
 
    ".gitignore"
 
    "build.cfg"
 
)
 

	
 
# Specify prefix to use in front of versions when tagging releases
 
# (for example if tags should be of format vX.Y.Z as opposed to
 
# X.Y.Z).
 
git_version_tag_prefix=""
 
EOF
 

	
 
    cat <<EOF > "$base_dir/.gitignore"
 
# Ignore IDE and backup files.
 
*~
 
.#*
 
@@ -460,12 +505,145 @@ function command_build() {
 
    rm -rf "$target_dir"
 

	
 
    success "Release built and placed under: $archive_file"
 
}
 

	
 

	
 
#
 
# Releases a mod version. Takes care of creating separate branch,
 
# making versioning changes/updates to mod information file and
 
# changelog, creating the tags, and even switching back the mod to
 
# development version.
 
#
 
# Arguments:
 
#
 
#   $1 (version)
 
#     Version of mod to release.
 
#
 
#   $2 (base_dir)
 
#     Base (top-level) directory with the mod files.
 
#
 
# Returns:
 
#
 
#   0 on success, 1 otherwise.
 
#
 
function command_release() {
 
    local version="$1"
 
    local base_dir="$2"
 

	
 
    # Prefix can be overridden via build configuration file.
 
    local git_version_tag_prefix=""
 

	
 
    local info_file changelog_file build_config
 
    local current_branch release_branch
 

	
 
    build_config="$base_dir/build.cfg"
 

	
 
    # Read build configuration.
 
    # shellcheck disable=SC1090 # build configuration file is create per-mod directory
 
    if [[ -f $build_config ]] && ! source "$build_config"; then
 
        error "Failed to load build configuration from: $build_config"
 
        return 1
 
    fi
 

	
 
    current_branch=$(git -C "$base_dir" rev-parse --abbrev-ref HEAD)
 
    release_branch="release-${version}"
 

	
 
    if [[ -d $base_dir/src ]]; then
 
        info_file="$base_dir/src/info.json"
 
        changelog_file="$base_dir/src/changelog.txt"
 
    else
 
        info_file="$base_dir/info.json"
 
        changelog_file="$base_dir/changelog.txt"
 
    fi
 

	
 
    if [[ ! -f $info_file ]]; then
 
        error "Could not locate info file under: $info_file"
 
        return 1
 
    fi
 

	
 
    if [[ ! -f $changelog_file ]]; then
 
        error "Could not locate changelog file under: $changelog_file"
 
        return 1
 
    fi
 

	
 
    if [[ $current_branch != master && $current_branch != main && $current_branch != devel ]]; then
 
        error "Releases must be based off of the master/main/devel branch."
 
        return 1
 
    fi
 

	
 
    if [[ $(git -C "$base_dir" status --short) != "" ]]; then
 
        error "Releases must be based off of a clean git working tree."
 
        return 1
 
    fi
 

	
 
    if ! git -C "$base_dir" checkout -b "$release_branch"; then
 
        error "Failed to create release branch: $release_branch"
 
        return 1
 
    fi
 

	
 
    # Update versioning information in info file and changelog.
 
    sed -i -e "s/999.999.999/$version/" "$info_file" "$changelog_file"
 

	
 
    # Update release date.
 
    sed -i -e "s/9999-99-99/$(date +%Y-%m-%d)/" "$changelog_file"
 

	
 
    # Drop empty changelog sections. Changelog sections begin with two
 
    # whitespaces at line beginning, followed by a non-whitespace
 
    # character.
 
    #
 
    # First sed expression:
 
    #
 
    # 1. Finds a section line.
 
    # 2. Reads the next line and adds it to pattern space. If the next
 
    #    line is not a section line, outputs the section it found
 
    #    (P). Otherwise it deletes the matched section line (D).
 
    # 3. Finally, it checks if the next line read (in step 2) is also
 
    #    a section line, and if it is, repeats the process for it (has
 
    #    to be done via goto directive since sed cannot be told to
 
    #    re-read the lines once they have been read with the N
 
    #    directive).
 
    #
 
    # Second sed expression deals with empty sections at the end of
 
    # the file (special case).
 
    sed -i -E -e '/^  [^ ]/{: checknext; N; /\n   /P; D; /^  [^ ]/b checknext}' "$changelog_file"
 
    sed -i -z -E -e 's/\n  [^ \n]+\n$/\n/' "$changelog_file"
 

	
 
    # Build the release.
 
    if ! command_build "$base_dir"; then
 
        return 1
 
    fi
 

	
 
    # Commit the changes and create a tag.
 
    if ! git -C "$base_dir" add "$changelog_file" "$info_file" || \
 
       ! git -C "$base_dir" commit --edit -m "Prepared release $version." || \
 
       ! git -C "$base_dir" tag -a -m "Release $version." "${git_version_tag_prefix}${version}"; then
 

	
 
        error "Failed to create release commit and tag."
 
        return 1
 
    fi
 

	
 
    # Switch back to development version.
 
    sed -i -e "s/$version/999.999.999/" "$info_file"
 
    # shellcheck disable=SC2094 # changelog file will be read in its entirety via $(<) first.
 
    cat > "$changelog_file" <<< "---------------------------------------------------------------------------------------------------
 
Version: 999.999.999
 
Date: 9999-99-99
 
$(< "$changelog_file")
 
"
 
    # Commit the changes.
 
    if ! git -C "$base_dir" add "$changelog_file" "$info_file" || \
 
       ! git -C "$base_dir" commit -m "Switched back to development version."; then
 
        error "Failed to create developement commit."
 
        return 1
 
    fi
 

	
 
    return 0
 
}
 

	
 

	
 
# Set-up colours for message printing if we're not piping and terminal is
 
# capable of outputting the colors.
 
_COLOR_TERMINAL=$(tput colors 2>&1)
 
if [[ -t 1 ]] && (( _COLOR_TERMINAL > 0 )); then
 
    _TEXT_BOLD=$(tput bold)
 
    _TEXT_WHITE=$(tput setaf 7)
 
@@ -577,12 +755,36 @@ elif [[ $COMMAND == build ]]; then
 
    fi
 

	
 
    if ! command_build "$MOD_DIRECTORY_PATH"; then
 
        exit "$ERROR_GENERAL"
 
    fi
 

	
 
elif [[ $COMMAND == release ]]; then
 

	
 
    MOD_VERSION="${1-}"
 
    MOD_DIRECTORY_PATH="${2:-.}"
 
    shift 2
 

	
 
    if [[ -z $MOD_VERSION ]]; then
 
        error "Mod version must be specified."
 
        exit "$ERROR_ARGUMENTS"
 
    elif [[ ! $MOD_VERSION =~ ^[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+$ ]]; then
 
        error "Mod version must be specified in x.y.z format (where x, y, and z are non-negative integers)."
 
        exit "$ERROR_ARGUMENTS"
 
    fi
 

	
 
    # Ensure that passed-in base directory is the repository root.
 
    if [[ ! -d $MOD_DIRECTORY_PATH/.git ]]; then
 
        error "Passed-in path does not point to base directory of the mod (must contain the .git sub-directory)."
 
        exit "$ERROR_ARGUMENTS"
 
    fi
 

	
 
    if ! command_release "$MOD_VERSION" "$MOD_DIRECTORY_PATH"; then
 
        exit "$ERROR_GENERAL"
 
    fi
 

	
 
else
 

	
 
    error "Unsupported command: $COMMAND"
 
    exit "$ERROR_ARGUMENTS"
 

	
 
fi
0 comments (0 inline, 0 general) First comment
You need to be logged in to comment. Login now