Skip to content

Commit

Permalink
Get the package version from git on CI
Browse files Browse the repository at this point in the history
  • Loading branch information
Dasperal committed Oct 19, 2024
1 parent d3cc83d commit dcc26c5
Show file tree
Hide file tree
Showing 7 changed files with 246 additions and 7 deletions.
2 changes: 1 addition & 1 deletion .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ ARG USER_GID=1001
# 5) Clean up
# 6) Setup user
RUN apt -y update && apt -y upgrade && \
apt -y install wget procps cmake && \
apt -y install wget procps cmake git && \
\
wget -P /tmp https://github.com/open-watcom/open-watcom-v2/releases/download/${OW2_RELEASE_VERSION}/${OW2_INSTALLER_NAME} && \
echo "${OW2_INSTALLER_SHA256} /tmp/${OW2_INSTALLER_NAME}" | sha256sum --check && \
Expand Down
9 changes: 4 additions & 5 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,10 @@ jobs:
# env:
# CC: ${{ matrix.config.compiler_name }}
run: |
rev_number=$(git rev-list --count HEAD)
export MAKEFLAGS=--keep-going
cmake --workflow --preset "${{ matrix.config.cmake_preset }}"
sha_short=$(echo ${{ github.sha }} | cut -c1-7)
echo "sha_short=$sha_short" >> $GITHUB_OUTPUT
echo "rev_number=r$rev_number" >> $GITHUB_OUTPUT
git_version=$(cmake -P ./cmake/UpdateRevision.cmake "git" 2>&1)
echo "version=$git_version" >> $GITHUB_OUTPUT
- name: Install
if: |
Expand All @@ -71,5 +70,5 @@ jobs:
github.repository == 'Russian-Doom/russian-doom-dos'
uses: actions/upload-artifact@v4
with:
name: russian-doom-dos-${{ steps.configure.outputs.rev_number }}-${{ steps.configure.outputs.sha_short }}-${{ matrix.config.build_suffix }}
name: russian-doom-dos-${{ steps.configure.outputs.version }}-${{ matrix.config.build_suffix }}
path: ./build/install/
23 changes: 22 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,28 @@
cmake_minimum_required(VERSION 3.0...3.29)

project("Russian Doom DOS" VERSION 1.9 LANGUAGES C NONE)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)

project("Russian Doom DOS" VERSION 1.8 LANGUAGES C NONE)

include(CMakeDependentOption)
include(Utils)

# Git info options
find_package(Git)
cmake_dependent_option(RD_GIT_NO_HASH "For Devs only! Don't run 'revision_check' at all" OFF "GIT_FOUND" ON)

# Update git_info.h
if(RD_GIT_NO_HASH)
# Use a function to avoid accidentally messing the real variables
configure_empty_git_info("cmake/git_info.h.in" "git_info.h")
else()
add_custom_target(revision_check
COMMAND "${CMAKE_COMMAND}" -P "\"${PROJECT_SOURCE_DIR}/cmake/UpdateRevision.cmake\"" "${GIT_EXECUTABLE}" "\"git_info.h\""
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
)
endif()

# Sources
add_subdirectory(audio)
add_subdirectory(src)

Expand Down
196 changes: 196 additions & 0 deletions cmake/UpdateRevision.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
#!/usr/bin/cmake -P

# UpdateRevision.cmake
#
# Public domain. This program uses git commands command to get
# various bits of repository status for a particular directory
# and writes it into a header file so that it can be used for a
# project's versioning.

# Boilerplate to return a variable from a function.
macro(ret_var VAR)
set(${VAR} "${${VAR}}" PARENT_SCOPE)
endmacro()

# Populate variables "Hash", "Timestamp", "Version_suffix" with relevant information
# from source repository. If anything goes wrong return something in "Error."
function(query_repo_info Tag ProjectDir)
execute_process(
COMMAND "${Git_executable}" log -1 "--format=%ai;%H"
WORKING_DIRECTORY "${ProjectDir}"
RESULT_VARIABLE Error
OUTPUT_VARIABLE CommitInfo
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(NOT "${Error}" STREQUAL "0")
ret_var(Error)
return()
endif()
list(GET CommitInfo 0 Timestamp)
list(GET CommitInfo 1 Hash)

ret_var(Hash)
ret_var(Timestamp)

execute_process(
COMMAND "${Git_executable}" rev-list "${Tag}.." --count
WORKING_DIRECTORY "${ProjectDir}"
RESULT_VARIABLE Error
OUTPUT_VARIABLE Commits_from_release
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)

if(NOT "${Error}" STREQUAL "0")
return()
endif()

if("${Commits_from_release}" STREQUAL "0")
return()
endif()

execute_process(
COMMAND "${Git_executable}" rev-parse --abbrev-ref HEAD
WORKING_DIRECTORY "${ProjectDir}"
RESULT_VARIABLE Error
OUTPUT_VARIABLE Branch
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)

if(NOT "${Error}" STREQUAL "0")
return()
endif()

if("${Branch}" STREQUAL "makepkg")
execute_process(
COMMAND "${Git_executable}" log -n 1 "--pretty='%(decorate:separator=;,prefix=,suffix=)'" HEAD
WORKING_DIRECTORY "${ProjectDir}"
RESULT_VARIABLE Error
OUTPUT_VARIABLE Branch
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)

if(NOT "${Error}" STREQUAL "0")
return()
endif()

list(GET Branch 1 Branch)
string(REPLACE "origin/" "" Branch "${Branch}")
endif()

if("${Branch}" STREQUAL "master")
set(Version_suffix "~${Commits_from_release}")
set(Display_version_suffix "-${Commits_from_release}")
set(On_master_branch 1)
ret_var(Version_suffix)
ret_var(Display_version_suffix)
ret_var(On_master_branch)
return()
endif()

execute_process(
COMMAND "${Git_executable}" rev-list origin/master.. --count
WORKING_DIRECTORY "${ProjectDir}"
RESULT_VARIABLE Error
OUTPUT_VARIABLE Commits_in_branch
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)

if(NOT "${Error}" STREQUAL "0")
return()
endif()

math(EXPR Commits_from_master "${Commits_from_release} - ${Commits_in_branch}" OUTPUT_FORMAT DECIMAL)
string(SUBSTRING "${Branch}" 0 1 Branch_short)

set(Version_suffix "~${Commits_from_master}+${Branch_short}${Commits_in_branch}")
set(Display_version_suffix "-${Commits_from_master}-${Branch_short}${Commits_in_branch}")
ret_var(Version_suffix)
ret_var(Display_version_suffix)
endfunction()

# Although configure_file doesn't overwrite the file if the contents are the
# same we can't easily observe that to change the status message. This
# function parses the existing file (if it exists) and puts the hash in
# variable "OldHash"
function(get_existing_hash File)
if(EXISTS "${File}")
file(STRINGS "${File}" OldHash LIMIT_COUNT 1)
if(OldHash)
string(SUBSTRING "${OldHash}" 3 -1 OldHash)
ret_var(OldHash)
endif()
endif()
endfunction()

function(get_project_version CmakeFile)
file(STRINGS "${CmakeFile}" Project_statement REGEX "project\(.*\)")
string(REGEX REPLACE "[()\" ]" ";" Project_statement "${Project_statement}")
if(Project_statement)
cmake_parse_arguments("PROJECT"
"" # List of Options
"VERSION" # List of Values
"" # List of Lists
${Project_statement}
)
ret_var(PROJECT_VERSION)
endif()
endfunction()

function(main)
if(CMAKE_ARGC LESS 4) # cmake -P UpdateRevision.cmake <path to git> [<OutputFile>]
message(NOTICE "Usage: ${CMAKE_ARGV2} <path to git> [<path to git_info.h>]")
return()
endif()
set(Git_executable "${CMAKE_ARGV3}")

get_filename_component(ScriptDir "${CMAKE_SCRIPT_MODE_FILE}" DIRECTORY)
get_filename_component(ProjectDir "${ScriptDir}" DIRECTORY)
get_project_version("${ProjectDir}/CMakeLists.txt")

query_repo_info("${PROJECT_VERSION}" "${ProjectDir}")

if(NOT Hash)
message(NOTICE "Failed to get commit info: ${Error}")
set(Hash "<unknown>")
set(Timestamp "<unknown>")
set(Version_suffix "")
set(Display_version_suffix "")
else()
string(SUBSTRING "${Hash}" 0 7 Hash_suffix)

if(NOT Version_suffix)
set(Version_suffix "")
set(Display_version_suffix "")
else()
String(APPEND Display_version_suffix " ${Hash_suffix}")
endif()

string(SUBSTRING "${Timestamp}" 0 10 Date)
String(APPEND Display_version_suffix " (${Date})")
endif()

if(CMAKE_ARGV4)
set(OutputFile "${CMAKE_ARGV4}")
get_existing_hash("${OutputFile}")
if("${Hash}${Version_suffix}" STREQUAL OldHash)
return()
endif()

configure_file("${ScriptDir}/git_info.h.in" "${OutputFile}" @ONLY)

message(STATUS "Configuring ${OutputFile} - updated to commit ${Hash_suffix}")
else()
if(On_master_branch)
message(NOTICE "${PROJECT_VERSION}${Version_suffix}")
else()
message(NOTICE "${PROJECT_VERSION}${Version_suffix}-${Hash_suffix}")
endif()
endif()
endfunction()

main()
8 changes: 8 additions & 0 deletions cmake/Utils.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# configure_empty_git_info(<Template> <Output>)
function(configure_empty_git_info Template Output)
set(Hash "<unknown>")
set(Timestamp "<unknown>")
set(Version_suffix "")
set(Display_version_suffix "")
configure_file("${Template}" "${Output}" @ONLY)
endfunction()
11 changes: 11 additions & 0 deletions cmake/git_info.h.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// @Hash@@Version_suffix@
//
// This file was automatically generated by the Cmake.
// Do not edit by hand.

#pragma once

#define GIT_SHA "@Hash@"
#define GIT_VERSION_SUFFIX "@Version_suffix@"
#define GIT_DISPLAY_VERSION_SUFFIX "@Display_version_suffix@"
#define GIT_TIME "@Timestamp@"
4 changes: 4 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ target_compile_options(rusdoom PRIVATE
-ei # use 4 bytes for enum
)

if(NOT RD_GIT_NO_HASH)
add_dependencies(rusdoom revision_check)
endif()

install(TARGETS rusdoom RUNTIME
DESTINATION .
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
Expand Down

0 comments on commit dcc26c5

Please sign in to comment.