parameters:
  - name: DependsOn
    type: object
  - name: SDKType
    type: string
  - name: Artifacts
    type: object
    default: []
  - name: TestPipeline
    type: boolean
    default: false
  - name: ArtifactName
    type: string
    default: 'not-specified'
  - name: TargetDocRepoName
    type: string
    default: ''
  - name: UseEsrpRelease
    type: boolean
    # A different environment will be passed in for service directories that have
    # live tests enabled for release and ReleaseDependsOnLiveTests is false
  - name: Environment
    type: string
    default: 'maven'

stages:
  # The signing stage is responsible for submitting binaries to ESRP for our official signing
  # where appropriate and also meeting any other signing requirements for particular artifacts,
  # in this case we do GPG signing in order to publish to Maven Central. At the moment signing
  # is protected by an approval check but this may be removed in the future.
  - stage: Signing
    dependsOn: ${{parameters.DependsOn}}
    jobs:
      - deployment: SignPackage
        environment: esrp
        timeoutInMinutes: 240
        variables:
          - template: /eng/pipelines/templates/variables/globals.yml
        pool:
          name: azsdk-pool-mms-ubuntu-2004-general
          vmImage: MMSUbuntu20.04
        strategy:
          runOnce:
            deploy:
              steps:
                - checkout: none

                - download: current
                  displayName: 'Download Artifact: ${{parameters.ArtifactName}}'
                  artifact: ${{parameters.ArtifactName}}

                - template: tools/java-esrp-signing/java-esrp-signing.yml@azure-sdk-build-tools
                  parameters:
                    Artifacts: ${{parameters.Artifacts}}
                    ArtifactDirectory: $(Pipeline.Workspace)/${{parameters.ArtifactName}}

                - publish: $(Pipeline.Workspace)/${{parameters.ArtifactName}}
                  artifact: ${{parameters.ArtifactName}}-signed
                  displayName: 'Store signed packages in ${{parameters.ArtifactName}}-signed artifact'

  # We generate two interdependent stages for each artifact listed in the ci.yml file, creates the release
  # in GitHub. The Release stage publishes to Maven Central. Both stages require approval since they
  # effectively burn the version number. For testing of packages prior to burning the version number -
  # the Validation step below publishes a package to a "burner" feed which is cleaned up after the
  # pipeline completes.
  - ${{if and(in(variables['Build.Reason'], 'Manual', ''), eq(variables['System.TeamProject'], 'internal'))}}:
    - stage:
      displayName: 'Releasing: ${{ length(parameters.Artifacts) }} libraries'
      dependsOn: Signing
      condition: and(succeeded(), ne(variables['SetDevVersion'], 'true'), ne(variables['Skip.Release'], 'true'), ne(variables['Build.Repository.Name'], 'Azure/azure-sdk-for-java-pr'))
      jobs:
        - deployment: TagRepository
          displayName: "Create release tag"
          condition: and(succeeded(), ne(variables['Skip.TagRepository'], 'true'))
          environment: ${{ parameters.Environment }}
          variables:
            - template: /eng/pipelines/templates/variables/globals.yml
          pool:
            name: azsdk-pool-mms-win-2022-general
            vmImage: windows-2022
          strategy:
            runOnce:
              deploy:
                steps:
                  - template: /eng/common/pipelines/templates/steps/sparse-checkout.yml
                  - template: /eng/common/pipelines/templates/steps/retain-run.yml
                  # No pattern, just download everything that's been signed
                  - download: current
                    displayName: 'Download Artifact: ${{parameters.ArtifactName}}-signed'
                    artifact: ${{parameters.ArtifactName}}-signed
                  - ${{ each artifact in parameters.Artifacts }}:
                    - template: /eng/common/pipelines/templates/steps/create-tags-and-git-release.yml
                      parameters:
                        ArtifactLocation: $(Pipeline.Workspace)/${{parameters.ArtifactName}}-signed/${{artifact.groupId}}/${{artifact.name}}
                        PackageRepository: Maven
                        ReleaseSha: $(Build.SourceVersion)

        - deployment: PublishPackage
          displayName: "Publish to Maven Central"
          condition: and(succeeded(), ne(variables['Skip.PublishPackage'], 'true'))
          # There are over 130 com.azure libraries. At roughly 3m 20s per ESRP release
          # this timeout should be enough to allow release of everything. Things should
          # change once ESRP has batch release enabled.
          timeoutInMinutes: 540
          environment: ${{ parameters.Environment }}
          dependsOn: TagRepository
          variables:
            - template: /eng/pipelines/templates/variables/globals.yml
          pool:
            name: azsdk-pool-mms-win-2022-general
            vmImage: windows-2022
          strategy:
            runOnce:
              deploy:
                steps:
                  - checkout: azure-sdk-build-tools
                    path: azure-sdk-build-tools
                  - template: /eng/common/pipelines/templates/steps/sparse-checkout.yml
                    parameters:
                      SkipCheckoutNone: true
                      Repositories:
                        - Name: Azure/azure-sdk-for-java
                          Commitish: $(Build.SourceVersion)
                          WorkingDirectory: $(Pipeline.Workspace)/azure-sdk-for-java
                  - download: current
                    displayName: 'Download Artifacts'
                    artifact: ${{parameters.ArtifactName}}-signed
                  - template: tools/gpg/gpg.yml@azure-sdk-build-tools
                  - ${{ if eq(parameters.UseEsrpRelease, 'true') }}:
                    - template: /eng/pipelines/templates/steps/java-publishing.yml
                      parameters:
                        ArtifactDirectory: $(Pipeline.Workspace)/${{parameters.ArtifactName}}-signed
                        OutputDirectory: $(Pipeline.Workspace)/EsrpPackages
                        Target: EsrpRelease
                        BuildToolsPath: $(Pipeline.Workspace)/azure-sdk-build-tools
                        JavaRepoRoot: $(Pipeline.Workspace)/azure-sdk-for-java
                    - template: /eng/common/pipelines/templates/steps/publish-artifact.yml
                      parameters:
                        ArtifactName: ${{parameters.ArtifactName}}-esrp-$(System.JobAttempt)
                        ArtifactPath: $(Pipeline.Workspace)/EsrpPackages
                  - ${{ else }}:
                    - template: /eng/pipelines/templates/steps/java-publishing.yml
                      parameters:
                        ArtifactDirectory: $(Pipeline.Workspace)/${{parameters.ArtifactName}}-signed
                        Target: MavenCentral
                        BuildToolsPath: $(Pipeline.Workspace)/azure-sdk-build-tools
                        JavaRepoRoot: $(Pipeline.Workspace)/azure-sdk-for-java
                    - template: /eng/common/pipelines/templates/steps/publish-artifact.yml
                      parameters:
                        ArtifactName: ${{parameters.ArtifactName}}-mavencentral-$(System.JobAttempt)
                        ArtifactPath: $(Pipeline.Workspace)/${{parameters.ArtifactName}}-signed
                  # After publishing to Maven, publish to the azure-sdk-for-java feed. The reason for
                  # this is that the azure-sdk-for-java feed will have the package available immediately
                  # whereas Maven can take several hours for the package to become available.
                  - template: /eng/pipelines/templates/steps/java-publishing.yml
                    parameters:
                      ArtifactDirectory: $(Pipeline.Workspace)/${{parameters.ArtifactName}}-signed
                      RepositoryUrl: https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-java/maven/v1
                      Target: JavaDevFeed
                      BuildToolsPath: $(Pipeline.Workspace)/azure-sdk-build-tools
                      JavaRepoRoot: $(Pipeline.Workspace)/azure-sdk-for-java
                  - template: /eng/common/pipelines/templates/steps/publish-artifact.yml
                    parameters:
                      ArtifactName: ${{parameters.ArtifactName}}-javadevfeed-$(System.JobAttempt)
                      ArtifactPath: $(Pipeline.Workspace)/${{parameters.ArtifactName}}-signed

        - deployment: UpdatePackageVersion
          displayName: "Update Package Version"
          condition: and(succeeded(), ne(variables['Skip.UpdatePackageVersion'], 'true'))
          environment: ${{ parameters.Environment }}
          dependsOn: PublishPackage
          variables:
            - template: /eng/pipelines/templates/variables/globals.yml
          pool:
            name: azsdk-pool-mms-win-2022-general
            vmImage: windows-2022
          strategy:
            runOnce:
              deploy:
                steps:
                  - download: none

                  - template: /eng/common/pipelines/templates/steps/sparse-checkout.yml
                    parameters:
                      Paths:
                        - '**/*.xml'
                        - '**/*.md'
                        - '!sdk/**/test-recordings/*'
                        - '!sdk/**/session-records/*'

                  - task: UsePythonVersion@0
                    displayName: 'Use Python $(PythonVersion)'
                    inputs:
                      versionSpec: $(PythonVersion)

                  # Apply the version increment to each library, which only updates the version_client.txt file,
                  # and then call to update_versions will then apply all of the updates.
                  - pwsh: |
                      $ArtifactsList = $('${{ convertToJson(parameters.Artifacts) }}' | ConvertFrom-Json | Select-Object name, groupId)
                      $ArtifactsList | Format-Table -Property GroupId, Name | Out-String | Write-Host
                      python --version
                      foreach($artifact in $ArtifactsList) {
                        python eng/versioning/set_versions.py --build-type ${{ parameters.SDKType }} --increment-version --ai $($artifact.name) --gi $($artifact.groupId)
                      }
                    displayName: Increment package versions

                  - script: |
                      python --version
                      python eng/versioning/update_versions.py --update-type library --build-type ${{ parameters.SDKType }} --avi --sr
                    displayName: Update pom files for incremented versions

                  - template: /eng/common/pipelines/templates/steps/create-pull-request.yml
                    parameters:
                      PRBranchName: increment-package-version-patch-release-$(Build.BuildId)
                      CommitMsg: "Increment package versions for patch releases"
                      PRTitle: "Increment versions for patch releases"
                      CloseAfterOpenForTesting: '${{ parameters.TestPipeline }}'

        - deployment: PublishDocsMs
          displayName: Docs.MS Release
          condition: and(succeeded(), ne(variables['Skip.PublishDocs'], 'true'))
          timeoutInMinutes: 180
          environment: ${{ parameters.Environment }}
          dependsOn: PublishPackage

          pool:
            name: azsdk-pool-mms-ubuntu-2004-general
            vmImage: MMSUbuntu20.04

          variables:
            - template: /eng/pipelines/templates/variables/globals.yml
            - name: DocValidationImageId
              value: azuresdkimages.azurecr.io/javarefautocr:latest

          strategy:
            runOnce:
              deploy:
                steps:
                  - template: /eng/common/pipelines/templates/steps/sparse-checkout.yml
                    parameters:
                      SkipCheckoutNone: true
                      Paths:
                        - sdk
                        - common/perf-test-core
                        - .github/CODEOWNERS
                        - '!sdk/**/test-recordings/*'
                        - '!sdk/**/session-records/*'
                  - download: current
                    displayName: 'Download Artifact: ${{parameters.ArtifactName}}'
                    artifact: ${{parameters.ArtifactName}}
                  - template: /eng/common/pipelines/templates/steps/update-docsms-metadata.yml
                    parameters:
                      PackageInfoLocations:
                        - ${{ each artifact in parameters.Artifacts }}:
                          - ${{if ne(artifact.skipPublishDocMs, 'true')}}:
                            - $(Pipeline.Workspace)/${{parameters.ArtifactName}}/PackageInfo/${{artifact.name}}.json
                      WorkingDirectory: $(System.DefaultWorkingDirectory)
                      TargetDocRepoOwner: 'Azure'
                      TargetDocRepoName: ${{parameters.TargetDocRepoName}}
                      Language: 'java'
                      SparseCheckoutPaths:
                        - docs-ref-services/
                        - metadata/
                      DocValidationImageId: "$(DocValidationImageId)"

                  - ${{ each artifact in parameters.Artifacts }}:
                    - ${{if ne(artifact.skipPublishDocMs, 'true')}}:
                      - template: /eng/pipelines/templates/steps/fetch-package-list.yml
                        parameters:
                          JavaDocJarLocation: "$(Pipeline.Workspace)/${{parameters.ArtifactName}}/${{artifact.groupId}}/${{artifact.name}}"
                          ArtifactName: ${{artifact.name}}
                          TargetBranch: $(TargetBranchName)
                          DocRepoLocation: $(DocRepoLocation)
                          TargetDocRepoName: ${{parameters.TargetDocRepoName}}
                          TargetDocRepoOwner: "Azure"

        - deployment: PublishDocs
          displayName: Publish Docs to GitHubIO Blob Storage
          condition: and(succeeded(), ne(variables['Skip.PublishDocs'], 'true'))
          timeoutInMinutes: 120
          environment: ${{ parameters.Environment }}
          dependsOn: PublishPackage
          variables:
            - template: /eng/pipelines/templates/variables/globals.yml
          pool:
            name: azsdk-pool-mms-win-2022-general
            vmImage: windows-2022
          strategy:
            runOnce:
              deploy:
                steps:
                  - template: /eng/common/pipelines/templates/steps/sparse-checkout.yml
                  - download: current
                    displayName: 'Download Artifact: ${{parameters.ArtifactName}}-signed'
                    artifact: ${{parameters.ArtifactName}}-signed
                  - ${{ each artifact in parameters.Artifacts }}:
                    - ${{if ne(artifact.skipPublishDocGithubIo, 'true')}}:
                      - pwsh: |
                          Get-ChildItem -Recurse $(Pipeline.Workspace)/${{parameters.ArtifactName}}-signed/${{artifact.groupId}}/${{artifact.name}}
                        workingDirectory: $(Pipeline.Workspace)
                        displayName: Output Visible Artifacts
                      - template: /eng/common/pipelines/templates/steps/publish-blobs.yml
                        parameters:
                          FolderForUpload: '$(Pipeline.Workspace)/${{parameters.ArtifactName}}-signed/${{artifact.groupId}}/${{artifact.name}}'
                          BlobSASKey: '$(azure-sdk-docs-prod-sas)'
                          BlobName: '$(azure-sdk-docs-prod-blob-name)'
                          TargetLanguage: 'java'
                          ArtifactLocation: $(Pipeline.Workspace)/${{parameters.ArtifactName}}-signed/${{artifact.groupId}}/${{artifact.name}}
                          # we override the regular script path because we have cloned the build tools repo as a separate artifact.
                          ScriptPath: 'eng/common/scripts/copy-docs-to-blobstorage.ps1'
