Skip to content

RPM/Yum/Zypper/Centos/Fedora/Suse packages #62

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Apr 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Binaries for programs and plugins
*.exe
output
.exe
*.exe~
*.dll
*.so
Expand Down
57 changes: 57 additions & 0 deletions build/azure-pipelines/package-common-create.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
parameters:
- name: OS
type: string
default:
- name: Type
type: string

steps:
- task: DownloadPipelineArtifact@2
inputs:
source: 'specific'
project: 'ae14e11c-7eb2-46af-b588-471e6116d635'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this be a friendly name instead of a guid?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or is it better to obfuscate our ADO names in the public repos?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The help says either:

Project | (Required) The project name or GUID from which to download the pipeline artifacts.

I am open either way. I think this can be the project name. Let me think on this.

pipeline: 500
runVersion: 'latest'
targetPath: '$(Pipeline.Workspace)'
- task: PowerShell@2
displayName: Set last tag to variable
inputs:
targetType: 'inline'
script: |
$VERSION_TAG = git describe --tags (git rev-list --tags --max-count=1)
$VERSION_TAG = $VERSION_TAG.substring(1) # Trim initial 'v'
Write-Host("##vso[task.setvariable variable=VERSION_TAG]$VERSION_TAG")
Write-Host($VERSION_TAG)
- task: CmdLine@2
displayName: 'Build ${{ parameters.OS }}/${{ parameters.Type }} distribution'
inputs:
script: release/${{ parameters.OS }}/${{ parameters.Type }}/pipeline.sh
workingDirectory: $(Build.SourcesCliDirectory)
env:
CLI_VERSION: $(VERSION_TAG)
BUILD_OUTPUT: $(Pipeline.Workspace)
BUILD_STAGINGDIRECTORY: $(Build.ArtifactStagingDirectory)
- task: EsrpCodeSigning@1
inputs:
ConnectedServiceName: 'Code Signing'
FolderPath: $(Build.ArtifactStagingDirectory)
Pattern: '*.${{ parameters.Type }}'
signConfigType: 'inlineSignParams'
inlineOperation: |
[
{
"KeyCode" : "CP-450779-Pgp",
"OperationCode" : "LinuxSign",
"Parameters" : {},
"ToolName" : "sign",
"ToolVersion" : "1.0"
}
]
SessionTimeout: '600'
MaxConcurrency: '50'
MaxRetryAttempts: '20'
- task: PublishPipelineArtifact@0
displayName: 'Publish Artifact: ${{ parameters.Type }}'
inputs:
targetPath: $(Build.ArtifactStagingDirectory)
artifactName: ${{ parameters.Type }}
25 changes: 25 additions & 0 deletions build/azure-pipelines/package-common-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
parameters:
- name: OS
type: string
default:
- name: Type
type: string

steps:
- task: PowerShell@2
displayName: Set last tag to variable
inputs:
targetType: 'inline'
script: |
$VERSION_TAG = git describe --tags (git rev-list --tags --max-count=1)
$VERSION_TAG = $VERSION_TAG.substring(1) # Trim initial 'v'
Write-Host("##vso[task.setvariable variable=VERSION_TAG]$VERSION_TAG")
Write-Host($VERSION_TAG)
- task: CmdLine@2
displayName: 'Test ${{ parameters.OS }}/${{ parameters.Type }} distribution'
inputs:
script: release/${{ parameters.OS }}/${{ parameters.Type }}/pipeline-test.sh
workingDirectory: $(Build.SourcesCliDirectory)
env:
CLI_VERSION: $(VERSION_TAG)
BUILD_STAGINGDIRECTORY: $(Build.ArtifactStagingDirectory)
30 changes: 30 additions & 0 deletions build/azure-pipelines/package-product.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# sqlcmd package pipeline

pr: none
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


variables:
Build.SourcesCliDirectory: '$(Build.SourcesDirectory)/'

stages:
- stage: CreatePackages
displayName: Create and Test Package Matrix
jobs:
- job: Package
strategy:
matrix:
rpm:
imageName: 'ubuntu-latest'
os: linux
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this entire stack is Linux-specific. Won't we need powershell or cmd scripts for Windows, and use a different signing profile?
Perhaps the template names should be based on the OS.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think docker and mac can follow this format, I think windows is the only odd one out. I was planning to deal with that when I get to the Windows PR, and make the fewest possible changes when I get to the Windows PR (it might just come down to pipeline.sh vs pipeline.cmd etc.!

type: rpm
pool:
vmImage: $(imageName)
steps:
- template: package-common-create.yml
parameters:
OS: $(os)
Type: $(type)
- template: package-common-test.yml
parameters:
OS: $(os)
Type: $(type)

18 changes: 18 additions & 0 deletions release/linux/rpm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
RPM Release

## Building RPM in CI/CD pipeline

Execute the following command from the root directory of this repository:

``` bash
./release/linux/rpm/pipeline.sh
```
Output will be sent to `./output/rpm`

To test the packages:

``` bash
./release/linux/rpm/pipeline-test.sh
```


27 changes: 27 additions & 0 deletions release/linux/rpm/build-rpm.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env bash

#------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
#------------------------------------------------------------------------------

# Description:
#
# Build a rpm `sqlcmd` package. This script is intended to be run in a
# container with the respective distro/image laid down.
#
# Usage:
# $ build-rpm.sh

set -exv

: "${CLI_VERSION:?CLI_VERSION environment variable not set.}"
: "${CLI_VERSION_REVISION:?CLI_VERSION_REVISION environment variable not set.}"

yum update -y
yum install -y rpm-build

export LC_ALL=en_US.UTF-8
export REPO_ROOT_DIR=`cd $(dirname $0); cd ../../../; pwd`

rpmbuild -v -bb --clean ${REPO_ROOT_DIR}/release/linux/rpm/sqlcmd.spec && cp /root/rpmbuild/RPMS/x86_64/* /mnt/output
106 changes: 106 additions & 0 deletions release/linux/rpm/pipeline-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#!/usr/bin/env bash

#------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
#------------------------------------------------------------------------------

# Description:
#
# Instructions to be invoked under the build CI pipeline in AzureDevOps.
#
# Kickoff rpm package tests against versions:
#
# -----------------------------------
# centos:centos8
# centos:centos7
# -----------------------------------
# fedora:31
# fedora:30
# fedora:29
# -----------------------------------
# opensuse/leap:latest
# -----------------------------------
#
# Usage:
# $ pipeline-test.sh

set -exv

: "${REPO_ROOT_DIR:=`cd $(dirname $0); cd ../../../; pwd`}"

CLI_VERSION=${CLI_VERSION:=0.0.1}
CLI_VERSION_REVISION=${CLI_VERSION_REVISION:=1}

BUILD_ARTIFACTSTAGINGDIRECTORY=${BUILD_ARTIFACTSTAGINGDIRECTORY:=${REPO_ROOT_DIR}/output/rpm}

YUM_DISTRO_BASE_IMAGE=( centos:centos7 centos:centos8 fedora:29 fedora:30 fedora:31 )
YUM_DISTRO_SUFFIX=( el7 el7 fc29 fc29 fc29 )

ZYPPER_DISTRO_BASE_IMAGE=( opensuse/leap:latest )
ZYPPER_DISTRO_SUFFIX=( el7 )

echo "=========================================================="
echo "CLI_VERSION: ${CLI_VERSION}"
echo "CLI_VERSION_REVISION: ${CLI_VERSION_REVISION}"
echo "BUILD_ARTIFACTSTAGINGDIRECTORY: ${BUILD_ARTIFACTSTAGINGDIRECTORY}"
echo "Distribution: ${YUM_DISTRO_BASE_IMAGE} ${ZYPPER_DISTRO_BASE_IMAGE}"
echo "=========================================================="

# -- yum installs --
for i in ${!YUM_DISTRO_BASE_IMAGE[@]}; do
image=${YUM_DISTRO_BASE_IMAGE[$i]}
suffix=${YUM_DISTRO_SUFFIX[$i]}

echo "=========================================================="
echo "Test rpm package on ${image} .${suffix}"
echo "=========================================================="
rpmPkg=sqlcmd-${CLI_VERSION}-${CLI_VERSION_REVISION}.${suffix}.x86_64.rpm

# Per: https://techglimpse.com/failed-metadata-repo-appstream-centos-8/
# change the mirrors to vault.centos.org where they will be archived permanently
mirrors=""
if [[ "${image}" == "centos:centos8" ]]; then
mirrors="cd /etc/yum.repos.d/ && \
sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* && \
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* && \ "
fi

script="${mirrors}
rpm --import https://packages.microsoft.com/keys/microsoft.asc && \
yum update -y && \
yum localinstall /mnt/artifacts/${rpmPkg} -y && \
sqlcmd --help"

docker pull ${image}
docker run --rm -v ${BUILD_ARTIFACTSTAGINGDIRECTORY}:/mnt/artifacts \
${image} \
/bin/bash -c "${script}"

echo ""
done

# -- zypper installs --
for i in ${!ZYPPER_DISTRO_BASE_IMAGE[@]}; do
image=${ZYPPER_DISTRO_BASE_IMAGE[$i]}
suffix=${ZYPPER_DISTRO_SUFFIX[$i]}

echo "=========================================================="
echo "Test rpm package on ${image} .${suffix}"
echo "=========================================================="
rpmPkg=sqlcmd-${CLI_VERSION}-${CLI_VERSION_REVISION}.${suffix}.x86_64.rpm
# If testing locally w/o signing, use `--allow-unsigned-rpm` but do not commit:
# zypper --non-interactive install --allow-unsigned-rpm /mnt/artifacts/${rpmPkg} && \

script="zypper --non-interactive install curl && \
rpm -v --import https://packages.microsoft.com/keys/microsoft.asc && \
zypper --non-interactive install /mnt/artifacts/${rpmPkg} && \
sqlcmd --help"

docker pull ${image}
docker run --rm -v ${BUILD_ARTIFACTSTAGINGDIRECTORY}:/mnt/artifacts \
${image} \
/bin/bash -c "${script}"

echo ""
done
57 changes: 57 additions & 0 deletions release/linux/rpm/pipeline.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env bash
#------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
#------------------------------------------------------------------------------

# Description:
#
# Instructions to be invoked under the build CI pipeline in AzureDevOps.
#
# Kickoff rpm package build. The build pipeline can then save it as an
# artifact as it sees fit.
#
# Usage:
#
# foundation images: `centos:centos7|fedora:29`
#
# $ pipeline.sh

set -exv

: "${REPO_ROOT_DIR:=`cd $(dirname $0); cd ../../../; pwd`}"

if [[ "${BUILD_OUTPUT}" != "" ]]; then
cp ${BUILD_OUTPUT}/SqlcmdLinuxAmd64/sqlcmd ${REPO_ROOT_DIR}/sqlcmd
fi

DIST_DIR=${BUILD_STAGINGDIRECTORY:=${REPO_ROOT_DIR}/output/rpm}
DISTRO_BASE_IMAGE=( centos:centos7 fedora:29 )

CLI_VERSION=${CLI_VERSION:=0.0.1}

echo "=========================================================="
echo "CLI_VERSION: ${CLI_VERSION}"
echo "CLI_VERSION_REVISION: ${CLI_VERSION_REVISION:=1}"
echo "Distribution Image: ${DISTRO_BASE_IMAGE}"
echo "Output location: ${DIST_DIR}"
echo "=========================================================="

mkdir -p ${DIST_DIR} || exit 1

for i in ${!DISTRO_BASE_IMAGE[@]}; do
image=${DISTRO_BASE_IMAGE[$i]}

echo "=========================================================="
echo "Build rpm on ${image}"
echo "=========================================================="

docker run --rm \
-v "${REPO_ROOT_DIR}":/mnt/repo \
-v "${DIST_DIR}":/mnt/output \
-v "${PIPELINE_WORKSPACE}":/mnt/workspace \
-e CLI_VERSION=${CLI_VERSION} \
-e CLI_VERSION_REVISION=${CLI_VERSION_REVISION:=1} \
"${image}" \
/mnt/repo/release/linux/rpm/build-rpm.sh
done
37 changes: 37 additions & 0 deletions release/linux/rpm/sqlcmd.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# RPM spec file for sqlcmd
# Definition of macros used - https://fedoraproject.org/wiki/Packaging:RPMMacros?rd=Packaging/RPMMacros

# .el7.centos -> .el7
%if 0%{?rhel}
%define dist .el%{?rhel}
%endif

%define name sqlcmd
%define release 1%{?dist}
%define version %{getenv:CLI_VERSION}
%define repo_path %{getenv:REPO_ROOT_DIR}
%define cli_lib_dir %{_libdir}/sqlcmd

%undefine _missing_build_ids_terminate_build
%global _missing_build_ids_terminate_build 0

Summary: MSSQL SQLCMD CLI Tools
License: https://github.com/microsoft/go-sqlcmd/blob/main/LICENSE
Name: %{name}
Version: %{version}
Release: %{release}
Url: https://github.com/microsoft/go-sqlcmd
BuildArch: x86_64

%description
SQLCMD CLI, a multi-platform command line experience for Microsoft SQL Server and Azure SQL.

%prep
%install

# Create executable
mkdir -p %{buildroot}%{_bindir}
cp %{repo_path}/sqlcmd %{buildroot}%{_bindir}

%files
%attr(0755,root,root) %{_bindir}/sqlcmd