1

오류없이 일찍 끝나는 Azure 함수에 대한 사용자 정의 일괄 처리 배포 스크립트가 있습니다. 나는 누군가가 내가 무슨 일이 일어나고 있는지 이해하도록 도와 줄 수 있기를 바라고있다.Azure 함수/Azure 웹 사이트 사용자 정의 배포 스크립트가 조기에 만료됩니다.

문제가있는 부분은 스크립트의 "사전 배포"섹션에 나타납니다하십시오 package.json이 마지막 두 커밋 사이에서 수정되지 않은 경우

for /F %%f in ('git.exe diff --name-only %PREVIOUS_SCM_COMMIT_ID% %SCM_COMMIT_ID% ^| grep package.json') do (
    SET PACKAGEJSON=%%~f 
    SET PKGFOLDER=!DEPLOYMENT_SOURCE!\!PACKAGEJSON:package.json=! 
    echo "NPM Install: !PKGFOLDER!package.json" 
    pushd "!PKGFOLDER!" 
    npm install --production --progress=false --cache-min=432000 
    npm install --save json-loader --progress=false --cache-min=432000 
    IF !ERRORLEVEL! NEQ 0 goto error 
    popd 
) 

, 스크립트는이 섹션으로 건너 뜁니다 예상하고 "배포"섹션을 계속 실행합니다.

package.json을 수정 한 경우 처음에는 코드가 예상대로 작동하고 npm 설치가 실행됩니다. 그러나 나중에 오류없이 끝나고 배포 섹션으로 넘어 가지 않습니다. 마지막 npm 설치가 실행 된 후 스크립트에서 추가 출력이 없습니다.

누구든지 내가 잘못 이해했는지 알 수 있습니까? 이것은 나에게 맞는 것 같습니다.

전체 스크립트는 아래이며, 다음 프로젝트의 일부입니다 : 문제의 https://github.com/securityvoid/.deploy

@if "%SCM_TRACE_LEVEL%" NEQ "4" @echo off 
@echo Started: %date% %time% 

:: ---------------------- 
:: KUDU Deployment Script 
:: Version: 1.0.12 
:: ---------------------- 

:: Prerequisites 
:: ------------- 

:: Verify node.js installed 
where node 2>nul >nul 
IF %ERRORLEVEL% NEQ 0 (
    echo Missing node.js executable, please install node.js, if already installed make sure it can be reached from current environment. 
    goto error 
) 

:: Setup 
:: ----- 

setlocal enabledelayedexpansion 

SET ARTIFACTS=%~dp0%..\artifacts 

IF NOT DEFINED DEPLOYMENT_SOURCE (
    SET DEPLOYMENT_SOURCE=%~dp0%. 
) 
echo "Deployment Source: %DEPLOYMENT_SOURCE%" 

IF NOT DEFINED DEPLOYMENT_DIST (
    SET DEPLOYMENT_DIST=%DEPLOYMENT_SOURCE%\dist 
) ELSE (
    ECHO "Deployement Dist already set" 
) 
echo "Deployment Dist: %DEPLOYMENT_DIST%" 

IF NOT DEFINED DEPLOYMENT_TARGET (
    SET DEPLOYMENT_TARGET=%ARTIFACTS%\wwwroot 
) 
echo "Deployment Target: %DEPLOYMENT_TARGET%" 

IF NOT DEFINED NEXT_MANIFEST_PATH (
    SET NEXT_MANIFEST_PATH=%ARTIFACTS%\manifest 

    IF NOT DEFINED PREVIOUS_MANIFEST_PATH (
    SET PREVIOUS_MANIFEST_PATH=%ARTIFACTS%\manifest 
) 
) 

IF NOT DEFINED KUDU_SYNC_CMD (
    :: Install kudu sync 
    echo Installing Kudu Sync 
    call npm install kudusync -g --silent 
    IF !ERRORLEVEL! NEQ 0 goto error 

    :: Locally just running "kuduSync" would also work 
    SET KUDU_SYNC_CMD=%appdata%\npm\kuduSync.cmd 
) 

for /F "tokens=5 delims=.\" %%a in ("%PREVIOUS_MANIFEST_PATH%") do SET PREVIOUS_SCM_COMMIT_ID=%%a 

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 
:: Pre-Deployment 
:: ---------- 
@echo "Initiating Pre-Deployment: %date% %time%" 
@echo "Previous Commit: %PREVIOUS_SCM_COMMIT_ID% Current Commit: %SCM_COMMIT_ID%" 
for /F %%f in ('git.exe diff --name-only %PREVIOUS_SCM_COMMIT_ID% %SCM_COMMIT_ID% ^| grep package.json') do (
    SET PACKAGEJSON=%%~f 
    SET PKGFOLDER=!DEPLOYMENT_SOURCE!\!PACKAGEJSON:package.json=! 
    echo "NPM Install: !PKGFOLDER!package.json" 
    pushd "!PKGFOLDER!" 
    npm install --production --progress=false --cache-min=432000 
    npm install --save json-loader --progress=false --cache-min=432000 
    IF !ERRORLEVEL! NEQ 0 goto error 
    popd 
) 


:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 
:: Deployment 
:: ---------- 

@echo "Initiating Deployment: %date% %time%" 

:: 1. Build Script 
node %DEPLOYMENT_SOURCE%\.deploy\deploy.js 

:: 2. KuduSync 
IF /I "%IN_PLACE_DEPLOYMENT%" NEQ "1" (
    call :ExecuteCmd "%KUDU_SYNC_CMD%" -v 50 -f "%DEPLOYMENT_DIST%" -t "%DEPLOYMENT_TARGET%" -n "%NEXT_MANIFEST_PATH%" -p "%PREVIOUS_MANIFEST_PATH%" -i ".git;.hg;.deployment;deploy.cmd" 
    IF !ERRORLEVEL! NEQ 0 goto error 
) 

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 
goto end 

:: Execute command routine that will echo out when error 
:ExecuteCmd 
setlocal 
set _CMD_=%* 
call %_CMD_% 
if "%ERRORLEVEL%" NEQ "0" echo Failed exitCode=%ERRORLEVEL%, command=%_CMD_% 
exit /b %ERRORLEVEL% 

:error 
endlocal 
echo An error has occurred during web site deployment. 
call :exitSetErrorLevel 
call :exitFromFunction 2>nul 

:exitSetErrorLevel 
exit /b 1 

:exitFromFunction 
() 

:end 
endlocal 
echo Finished successfully. 
+0

결말 전에 얼마나 걸립니까? 항상 같은가요? 또한 앱이 소비 모드 또는 앱 서비스 계획 모드입니까? –

+0

소비 모드 및 매우 빠른. NPM 명령을 실행하는 데 약 60-90 초가 소요됩니다. 항상 정확한 시간대라고 할 수는 없습니다. 또한 SCM_COMMAND_IDLE_TIMEOUT을 900 초로 늘 렸습니다. – Doug

+0

무슨 일인지 잘 모르겠습니다. 확인해야 할 것은 Kudu w3wp가 어떻게 든 충돌하는지 여부입니다. PID가 변경되는지 (scm 하나의 경우) 전에 Kudu 프로세스 관리자를 볼 수 있습니다. –

답변

4

소스는 npm 배치 파일 것입니다. 배치 파일 (배치 파일)이 다른 배치 파일을 호출하면 실행 흐름은 호출 된 호출로 전송되고 일단 작업이 끝나면 실행 흐름은 호출자에게 반환되지 않습니다.

이 동작은 call 명령을 사용하여 호출을 완료하면 변경됩니다.

call npm .... 

실행 제어가 호출 된 배치 파일로 전송되고 끝나면 실행 흐름이 호출자에게 반환됩니다.

참고 : 노출 된 동작은 지연되지 않는 프로세스를 단순화 한 것입니다. 배치 파일은 메모리 내에서 실행됩니다 "컨텍스트". call 명령이 없으면 호출 된 배치 파일은 호출자 "context"call 명령으로 바꿉니다. 새 "context"이 작성됩니다.

또 다른 질문이 있습니다. 배치 npm 일괄 파일 전송 실행 흐름을 호출하고 반환하지 않으면 두 번째 npm 명령이 실행되는 이유는 무엇입니까?

배치 파일 (또는 명령 줄)을 실행하는 동안 코드 블록 (괄호로 묶인 코드)이 메모리에로드되고 전체적으로 구문 분석됩니다. for 명령이 메모리에 저장되고 해당 do 절에 포함 된 모든 명령은 루프가 끝날 때까지 계속 실행됩니다.(호출 된 컨텍스트로 대체)이 경우에 해당하지만, 첫 번째 npm 번 (call없이) 호출 된 호출자 배치 "컨텍스트"하지 폐기 된, 나머지 :

참고명령 줄 컨텍스트배치 상황에서 상기 "컨텍스트" 버리고 같이 setlocal 되돌릴되었으며 변수 변경 directoy하지 실행되는 for 루프 명령 (가 메모리에 아직) 변경 및 지연된 확장은 버려집니다.

+0

큰 설명에 감사드립니다. 이것은 정말로 흥미 롭습니다! – Doug