diff --git a/.gitignore b/.gitignore index c96abe90..9f05de2b 100644 --- a/.gitignore +++ b/.gitignore @@ -340,7 +340,8 @@ ASALocalRun/ healthchecksdb # Exclude tools folder -src/MSBuild.Sdk.SqlProj/tools/ +src/MSBuild.Sdk.SqlProj/tools/* +!src/MSBuild.Sdk.SqlProj/tools/container/ # Exclude generated Dacpac's *.dacpac diff --git a/src/MSBuild.Sdk.SqlProj/Sdk/Sdk.props b/src/MSBuild.Sdk.SqlProj/Sdk/Sdk.props index 8e8635ee..4d6e7e7e 100644 --- a/src/MSBuild.Sdk.SqlProj/Sdk/Sdk.props +++ b/src/MSBuild.Sdk.SqlProj/Sdk/Sdk.props @@ -10,6 +10,7 @@ $(MSBuildAllProjects);$(MsBuildThisFileFullPath) Sql150 .dacpac + 170.2.70 diff --git a/src/MSBuild.Sdk.SqlProj/Sdk/Sdk.targets b/src/MSBuild.Sdk.SqlProj/Sdk/Sdk.targets index 0b0eb508..9b6b566e 100644 --- a/src/MSBuild.Sdk.SqlProj/Sdk/Sdk.targets +++ b/src/MSBuild.Sdk.SqlProj/Sdk/Sdk.targets @@ -310,4 +310,74 @@ + + + + + $(MSBuildThisFileDirectory)..\tools\container\sqlpackage.Dockerfile + + + $([System.String]::Copy('$(MSBuildProjectName)').ToLowerInvariant().Trim())-publisher + $([System.String]::Copy('$(Configuration)').ToLowerInvariant().Trim()) + + + $(SqlPackageVersion) + + + $(MSBuildProjectDirectory)\.container + $(MSBuildProjectName).dacpac + $(ContainerStagingDir)\$(ContainerDacpacName) + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/MSBuild.Sdk.SqlProj/tools/container/sqlpackage.Dockerfile b/src/MSBuild.Sdk.SqlProj/tools/container/sqlpackage.Dockerfile new file mode 100644 index 00000000..ef7db16b --- /dev/null +++ b/src/MSBuild.Sdk.SqlProj/tools/container/sqlpackage.Dockerfile @@ -0,0 +1,46 @@ +# Base image: ships with the SDK +ARG BASE_IMAGE=mcr.microsoft.com/dotnet/runtime:8.0 +FROM ${BASE_IMAGE} +ARG SQLPACKAGE_VERSION +ARG DACPAC_NAME +ENV DACPAC_NAME=${DACPAC_NAME} + +# Install sqlpackage dependencies and pull from NuGet +# - Supports native (platform zip) and dotnet tool layouts +# - Installs a stable wrapper in /usr/local/bin/sqlpackage +RUN set -eux; \ + apt-get update \ + && apt-get install -y --no-install-recommends ca-certificates curl unzip \ + && curl -L -o /tmp/sqlpackage.nupkg "https://globalcdn.nuget.org/packages/microsoft.sqlpackage.${SQLPACKAGE_VERSION}.nupkg" \ + && mkdir -p /opt/sqlpackage-src /opt/sqlpackage \ + && unzip -q /tmp/sqlpackage.nupkg -d /opt/sqlpackage-src \ + && inner="$(find /opt/sqlpackage-src -type f -iname '*linux-x64*.zip' | head -n1 || true)" \ + && if [ -n "$inner" ]; then \ + unzip -q "$inner" -d /opt/sqlpackage; \ + else \ + cp -R /opt/sqlpackage-src/tools/*/any/* /opt/sqlpackage/; \ + fi \ + && printf '#!/usr/bin/env bash\nset -euo pipefail\nif [ -x /opt/sqlpackage/sqlpackage ]; then exec /opt/sqlpackage/sqlpackage "$@"; elif [ -f /opt/sqlpackage/sqlpackage.dll ]; then exec dotnet /opt/sqlpackage/sqlpackage.dll "$@"; else echo "sqlpackage not found"; exit 127; fi\n' > /usr/local/bin/sqlpackage \ + && chmod +x /usr/local/bin/sqlpackage \ + && rm -rf /var/lib/apt/lists/* /tmp/* /opt/sqlpackage-src \ + # Create entrypoint wrapper as root: + # - Bakes in `-Action:Publish` and `-SourceFile:/work/$DACPAC_NAME` + # - Forwards user-supplied args to sqlpackage + && install -d /usr/local/bin \ + && printf '%s\n' \ + '#!/usr/bin/env bash' \ + 'set -euo pipefail' \ + 'exec sqlpackage -Action:Publish -SourceFile:/work/"${DACPAC_NAME}" "$@"' \ + | tee /usr/local/bin/docker-entrypoint >/dev/null \ + && chmod +x /usr/local/bin/docker-entrypoint + +# Staging: the SDK copies all dacpacs into /work at build time +WORKDIR /work +COPY ./.container/*.dacpac /work/ + +# Drop privileges to a non-root user +RUN useradd -m runner +USER runner + +# Exec-form ENTRYPOINT for proper signal handling and linter compliance +ENTRYPOINT ["/usr/local/bin/docker-entrypoint"]