microsoft/gctoolkit
Publicmirrored fromhttps://github.com/microsoft/gctoolkitAvailable
.devops/gctoolkit-release.yml
271lines · modecode
| 1 | # Release GCToolkit to Maven Central |
| 2 | # |
| 3 | # Builds and tests the binaries. |
| 4 | # Signs the artifacts and generates SHA checksums. |
| 5 | # Publishes the artifacts to Maven Central. |
| 6 | |
| 7 | # This pipeline is triggered manually. |
| 8 | trigger: none |
| 9 | pr: none |
| 10 | |
| 11 | parameters: |
| 12 | - name: release_tag |
| 13 | type: string |
| 14 | displayName: Release Tag |
| 15 | |
| 16 | - name: release_type |
| 17 | type: string |
| 18 | displayName: Release Type |
| 19 | default: dry-run |
| 20 | values: |
| 21 | - dry-run |
| 22 | - release |
| 23 | |
| 24 | variables: |
| 25 | JAVA_HOME_11_X64: /usr/lib/jvm/msopenjdk-11 |
| 26 | GCTOOLKIT_TAG: ${{ parameters.release_tag }} |
| 27 | |
| 28 | resources: |
| 29 | repositories: |
| 30 | - repository: gctoolkit |
| 31 | type: github |
| 32 | endpoint: Github-Java-Engineering |
| 33 | name: microsoft/gctoolkit |
| 34 | ref: refs/tags/$(GCTOOLKIT_TAG) |
| 35 | |
| 36 | - repository: 1esPipelines |
| 37 | type: git |
| 38 | name: 1ESPipelineTemplates/1ESPipelineTemplates |
| 39 | ref: refs/tags/release |
| 40 | |
| 41 | extends: |
| 42 | template: v1/1ES.Official.PipelineTemplate.yml@1esPipelines |
| 43 | parameters: |
| 44 | pool: |
| 45 | name: JEG-test-pool-x64 |
| 46 | os: linux |
| 47 | sdl: |
| 48 | sourceAnalysisPool: |
| 49 | name: JEG-windows2022-x64-release |
| 50 | os: windows |
| 51 | sourceRepositoriesToScan: |
| 52 | exclude: |
| 53 | - repository: gctoolkit |
| 54 | credscan: |
| 55 | suppressionsFile: $(Build.SourcesDirectory)/.devops/credscan/suppressions.json |
| 56 | |
| 57 | stages: |
| 58 | - stage: Release_GCToolkit |
| 59 | jobs: |
| 60 | - job: build_gctoolkit |
| 61 | workspace: |
| 62 | clean: all |
| 63 | displayName: Build GCToolkit with Maven |
| 64 | templateContext: |
| 65 | # Disable Defender for Linux since it is not supported by Azure Linux. |
| 66 | # More info here: https://eng.ms/docs/cloud-ai-platform/devdiv/one-engineering-system-1es/1es-docs/1es-pipeline-templates/features/sdlanalysis/antimalware |
| 67 | sdl: |
| 68 | antimalwareScan: |
| 69 | enabled: false |
| 70 | justificationForDisabling: Disabling Defender for Linux as its not supported in Azure Linux 3 |
| 71 | outputs: |
| 72 | - output: pipelineArtifact |
| 73 | targetPath: $(Build.ArtifactStagingDirectory)/staging |
| 74 | artifactName: staged-artifacts |
| 75 | |
| 76 | steps: |
| 77 | - checkout: gctoolkit |
| 78 | path: gctoolkit |
| 79 | clean: true |
| 80 | |
| 81 | # Find out what is installed on the agents... |
| 82 | - bash: | |
| 83 | echo "Installed Tools and versions:" |
| 84 | find /opt/hostedtoolcache -mindepth 1 -type d | while read dir; do |
| 85 | if [[ "$dir" == *jdk* ]]; then |
| 86 | echo "👉 $dir" |
| 87 | else |
| 88 | echo "$dir" |
| 89 | fi |
| 90 | done |
| 91 | displayName: 'Show installed tools' |
| 92 | |
| 93 | # Use modern Java to build |
| 94 | - task: JavaToolInstaller@0 |
| 95 | inputs: |
| 96 | versionSpec: '11' |
| 97 | jdkArchitectureOption: 'x64' |
| 98 | jdkSourceOption: 'PreInstalled' |
| 99 | env: |
| 100 | JAVA_HOME_11_X64: $(JAVA_HOME_11_X64) |
| 101 | displayName: 'Set Java to v11' |
| 102 | |
| 103 | # download signing keys from Azure Key Vault |
| 104 | - task: AzureKeyVault@2 |
| 105 | displayName: Download GPG signing keys |
| 106 | inputs: |
| 107 | azureSubscription: 'JEG-Infrastructure' |
| 108 | KeyVaultName: 'juniper-keyvault' |
| 109 | SecretsFilter: 'javask-gpg-passphrase,javask-gpg-private,javask-gpg-public,javask-gpg-trust' |
| 110 | RunAsPreJob: false |
| 111 | |
| 112 | # base64 decode signing keys |
| 113 | - bash: | |
| 114 | echo "Base64 decoding keys..." |
| 115 | echo "$(javask-gpg-private)" | base64 -d > private.asc |
| 116 | echo "$(javask-gpg-public)" | base64 -d > public.asc |
| 117 | echo "$(javask-gpg-trust)" | base64 -d > trust.gpg |
| 118 | workingDirectory: $(Agent.BuildDirectory) |
| 119 | displayName: Base64 decode secret |
| 120 | |
| 121 | # import signing keys into GPG |
| 122 | - bash: | |
| 123 | echo "GPG importing keys..." |
| 124 | echo $(javask-gpg-passphrase) | gpg --batch --passphrase-fd 0 --import $(Agent.BuildDirectory)/private.asc |
| 125 | echo $(javask-gpg-passphrase) | gpg --batch --passphrase-fd 0 --import $(Agent.BuildDirectory)/public.asc |
| 126 | displayName: GPG import keys |
| 127 | |
| 128 | # restore owner trust |
| 129 | - bash: | |
| 130 | echo "GPG restore owner trust..." |
| 131 | gpg --import-ownertrust $(Agent.BuildDirectory)/trust.gpg |
| 132 | displayName: GPG restore owner trust |
| 133 | |
| 134 | # Now that all the keys and whatnot are setup, do the build... |
| 135 | - bash: | |
| 136 | mkdir ~/.m2 \|| true |
| 137 | cp $(Build.SourcesDirectory)/.devops/feed-settings.xml ~/.m2/settings.xml |
| 138 | displayName: 'Copy feed-settings to .m2' |
| 139 | |
| 140 | # Ensure authentication is in place for our use of internal DevDiv feeds |
| 141 | - task: MavenAuthenticate@0 |
| 142 | inputs: |
| 143 | artifactsFeeds: 'java-engineering-feed' |
| 144 | displayName: 'Maven auth for DevDiv' |
| 145 | |
| 146 | - bash: | |
| 147 | RELEASE_VERSION=$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout | cut -d'-' -f1) |
| 148 | echo "##vso[task.setvariable variable=RELEASE_VERSION]$RELEASE_VERSION" |
| 149 | displayName: 'Set RELEASE_VERSION' |
| 150 | |
| 151 | - bash: | |
| 152 | ./mvnw \ |
| 153 | -B -Prelease \ |
| 154 | -DaltDeploymentRepository=local::file:$(Build.ArtifactStagingDirectory)/staging \ |
| 155 | deploy |
| 156 | displayName: 'Build and deploy to local staging directory' |
| 157 | |
| 158 | # Remove .sha1 and .md5 files. |
| 159 | # Generate .sha256 after signing. |
| 160 | - bash: | |
| 161 | find staging \ |
| 162 | -type f \ |
| 163 | -name "*.sha1" \ |
| 164 | -delete -o \ |
| 165 | -name "*.md5" \ |
| 166 | -delete |
| 167 | displayName: 'Remove .sha1 and .md5 files' |
| 168 | workingDirectory: $(Build.ArtifactStagingDirectory) |
| 169 | |
| 170 | # ESRP Sign all jars in the gctoolkit staging directory |
| 171 | - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@5 |
| 172 | displayName: ESRP Java JAR Signing |
| 173 | inputs: |
| 174 | ConnectedServiceName: 'JEG-Tooling-Prod' |
| 175 | AppRegistrationClientId: '516af6d8-6ab4-4069-8f64-b18c64d16688' |
| 176 | AppRegistrationTenantId: '33e01921-4d64-4f8c-a055-5bdaffd5e33d' |
| 177 | AuthAKVName: 'JEG-tooling-kv' |
| 178 | AuthCertName: 'JEG-Tooling-auth' |
| 179 | AuthSignCertName: 'GCToolKit-ESRP' |
| 180 | FolderPath: '$(Build.ArtifactStagingDirectory)/staging' |
| 181 | Pattern: '**/*-$(RELEASE_VERSION)*.jar' |
| 182 | UseMinimatch: true |
| 183 | signConfigType: 'inlineSignParams' |
| 184 | inlineOperation: | |
| 185 | [ |
| 186 | { |
| 187 | "KeyCode": "CP-447347-Java", |
| 188 | "OperationCode": "JavaSign", |
| 189 | "ToolName": "sign", |
| 190 | "ToolVersion": "1.0", |
| 191 | "Parameters": { |
| 192 | "SigAlg": "SHA256withRSA", |
| 193 | "Timestamp": "-tsa http://sha256timestamp.ws.digicert.com/sha256/timestamp" |
| 194 | } |
| 195 | }, |
| 196 | { |
| 197 | "KeyCode": "CP-447347-Java", |
| 198 | "OperationCode": "JavaVerify", |
| 199 | "ToolName": "sign", |
| 200 | "ToolVersion": "1.0", |
| 201 | "Parameters": {} |
| 202 | } |
| 203 | ] |
| 204 | SessionTimeout: '120' |
| 205 | MaxConcurrency: '50' |
| 206 | MaxRetryAttempts: '5' |
| 207 | VerboseLogin: true |
| 208 | |
| 209 | # gpg sign all artifacts in the gctoolkit staging directory |
| 210 | # this will create a .asc file for each file in the directory. This is a detached signature |
| 211 | # required to publish into Maven Central. |
| 212 | - bash: | |
| 213 | for file in `find staging -type f -name *-$(RELEASE_VERSION)*.jar -o -name *-$(RELEASE_VERSION)*.pom`; do |
| 214 | echo $(javask-gpg-passphrase) | gpg --pinentry-mode loopback --passphrase-fd 0 -ab $file |
| 215 | done |
| 216 | workingDirectory: $(Build.ArtifactStagingDirectory) |
| 217 | displayName: GPG Signing |
| 218 | |
| 219 | # generate sha256sums for all files in the staging directory |
| 220 | - bash: | |
| 221 | for file in `find staging -type f`; do |
| 222 | sha256sum $file > $file.sha256 |
| 223 | done |
| 224 | workingDirectory: $(Build.ArtifactStagingDirectory) |
| 225 | displayName: Create sha256sums |
| 226 | |
| 227 | |
| 228 | # Release jobs have to be separated from build jobs for our internal release service to be compliant |
| 229 | - job: release_gctoolkit_to_maven_central |
| 230 | dependsOn: build_gctoolkit |
| 231 | workspace: |
| 232 | clean: all |
| 233 | displayName: Release GCToolkit to Maven Central |
| 234 | templateContext: |
| 235 | type: releaseJob |
| 236 | isProduction: true |
| 237 | inputs: # Pull the staged artifacts from the build job. |
| 238 | - input: pipelineArtifact |
| 239 | artifactName: staged-artifacts |
| 240 | targetPath: '$(Build.ArtifactStagingDirectory)/staging' |
| 241 | |
| 242 | steps: |
| 243 | # ESRP Release task docs at aka.ms/esrp under 'ESRP Portal Help' |
| 244 | - task: EsrpRelease@8 |
| 245 | inputs: |
| 246 | connectedservicename: 'JEG-Tooling-Prod' |
| 247 | keyvaultname: 'JEG-tooling-kv' |
| 248 | authcertname: 'JEG-Tooling-auth' |
| 249 | signcertname: 'GCToolKit-ESRP' |
| 250 | clientid: '516af6d8-6ab4-4069-8f64-b18c64d16688' |
| 251 | intent: 'PackageDistribution' |
| 252 | # Test with contentype PyPI to avoid publishing to Maven Central |
| 253 | # NOTE: This is the guidance given in ESRP portal for testing |
| 254 | # the flow during dry-runs, see aka.ms/esrp. |
| 255 | ${{ if eq(parameters.release_type, 'release') }}: |
| 256 | contenttype: 'Maven' |
| 257 | ${{ else }}: |
| 258 | contenttype: 'PyPI' |
| 259 | contentsource: 'Folder' |
| 260 | folderlocation: '$(Build.ArtifactStagingDirectory)/staging/com/microsoft/gctoolkit' |
| 261 | waitforreleasecompletion: true |
| 262 | owners: 'dekeeler@microsoft.com' |
| 263 | approvers: 'maverbur@microsoft.com,john.oliver@microsoft.com' |
| 264 | serviceendpointurl: 'https://api.esrp.microsoft.com' |
| 265 | mainpublisher: 'ESRPRELPACMAN' |
| 266 | domaintenantid: '33e01921-4d64-4f8c-a055-5bdaffd5e33d' |
| 267 | displayName: 'Publish to Maven Central' |
| 268 | # For non-release runs, allow this task to fail (it should!) so the |
| 269 | # pipeline does not appear to fail when it doesn't. |
| 270 | continueOnError: ${{ ne(parameters.release_type, 'release') }} |
| 271 | |
| 272 | |