justinmassiot
3/17/2020 - 3:06 PM

Create a Redmine project through the API

Referenced at https://gotomation.info/2020/04/redmine-api-create-project/

Dependencies:

  • cURL for Windows (select “CURL” from the navigation menu)
  • iconv / gettext for Windows
  • xmlstarlet for Windows

After having downloaded all the dependencies and the *.bat script, adjust the parameters to fit your installation. Finally, double-click the script to run it!

@echo off

:: All parameters are defined here

:: path to external tools (*without* preceding backslash)
:: IMPORTANT NOTE: **do not use spaces** for 'path_xmlstarlet' because xml.exe does not support them; this is a bug
set path_iconv=gettext0.20.1-iconv1.16-shared-64\bin\iconv.exe
set path_curl=curl_769_1_ssl\curl.exe
set path_xmlstarlet=xmlstarlet-1.6.1-win32\xmlstarlet-1.6.1\xml.exe

:: URL of the Redmine installation (without ending slash)
set redmine_url=http://mydomain.ext/redmine
:: name of the (temporary) XML file which will contain the request to the Redmine API
set filename_redmine_request=api_request.xml
:: same as above, but with UTF-8 encoded content
set filename_redmine_request_utf8=api_request_utf8.xml
:: name of the (temporary) XML file which will contain the answer of the Redmine API
set filename_redmine_result=redmine_result.xml
:: is the module publicly available on Redmine (true | false)
set redmine_project_public=false


:: get the current command line character encoding (CP = Code Page), for encoding conversion with iconv
:: https://technet.microsoft.com/fr-fr/library/cc733037%28v=ws.10%29.aspx
for /f "tokens=1,* delims=:" %%a in ('chcp') do (
  :: get only the CP numeric code
  for /f "tokens=* delims= " %%i in ("%%b") do set cp=CP%%i
)

:: Prompt the user for the module name and description
echo ----------
echo Project information
echo /!\ single quotes (') and double quotes (") are forbidden
echo --
set /p redmine_project_name="Project name:       "
set /p redmine_project_id="Project identifier: "
echo.
echo ----------
:: Prompt the user for its Redmine credentials
echo User credentials
echo --
echo Do not forget: you must have a role "manager" or "administrator" to be allowed to create a project into Redmine.
set /p userlogin="Enter your Redmine login   : "
set /p userpass="Enter your Redmine password: "
echo.

:: Write to a file the data to be passed to the Redmine API request
echo ^<project^> > "%filename_redmine_request%"
echo   ^<name^>%redmine_project_name%^</name^> >> "%filename_redmine_request%"
echo   ^<identifier^>%redmine_project_id%^</identifier^> >> "%filename_redmine_request%"
echo   ^<homepage^>^</homepage^> >> "%filename_redmine_request%"
echo   ^<parent_id^>^</parent_id^> >> "%filename_redmine_request%"
echo   ^<is_public^>%redmine_project_public%^</is_public^> >> "%filename_redmine_request%"
echo ^</project^> >> "%filename_redmine_request%"
:: convert the file into the UTF-8 characters set
"%path_iconv%" -f %cp% -t utf-8 "%filename_redmine_request%" > "%filename_redmine_request_utf8%"
if %ErrorLevel% neq 0 goto script_failure

:: Create the project in Redmine (http://curl.haxx.se/docs/manpage.html ; http://www.redmine.org/projects/redmine/wiki/Rest_Projects#Creating-a-project) , write the response code to a variable and write the answer content (XML) in a file
for /f "tokens=*" %%i in ('call "%path_curl%" --silent --write-out "%%{http_code}" --request POST --header "Content-Type: application/xml" --user %userlogin%:%userpass% %redmine_url%/projects.xml --data @"%filename_redmine_request_utf8%" --output "%filename_redmine_result%"') do set response_code=%%i
:: an empty response code means a probable cURL failure
if ["%response_code%"] == [""] goto script_failure

:: Now we try to understand the result
::   201 Created: project was created
::   422 Unprocessable Entity: project was not created due to validation failures (response body contains the error messages)
::   403 may be returned if the user does not have sufficient rights to create a project
::   500 may be returned if the data content is malformed
:: we look at the first character of the response code to see if it is 2**
if %response_code:~0,1% equ 2 goto redmine_good
echo The creation of the project '%redmine_project_name%' (ID = %redmine_project_id%) into Redmine has failed (code %response_code%)

:: If there is an error, check if the XML result file is well formatted to be parsed
for /f "tokens=*" %%i in ('call "%path_xmlstarlet%" validate "%filename_redmine_result%"') do set xml_is_valid=%%i
:: an empty %xml_is_valid% variable means a probable "xml.exe validate" failure
if ["%xml_is_valid%"] == [""] goto prompt_cleanup
:: if %xml_is_valid% contains the word "invalid", then the XML cannot be parsed
if not x"%xml_is_valid:invalid=%"==x"%xml_is_valid%" goto prompt_cleanup
:: if the XML file is good, we can extract the error message
echo   with the following message:
:: read the <error> tag from the XML and show it in the console
"%path_xmlstarlet%" select -t -v "//error" "%filename_redmine_result%"
echo.
goto prompt_cleanup

:redmine_good
echo The Redmine project '%redmine_project_name%' (ID = %redmine_project_id%) has been created. (code %response_code%)
pause
goto do_cleanup

:script_failure
echo We are sorry, something went wrong with the script or its dependencies.
:prompt_cleanup
set /p inspect="Hit Enter to quit, or k (lowercase) to keep the temporary files (if any) for further inspection "
if ["%inspect%"] == ["k"] goto eof

:do_cleanup
:: remove temporary files
del %filename_redmine_request%
del %filename_redmine_request_utf8%
del %filename_redmine_result%

:eof