Deploy a specific project to NuGet with a matrix configuration - continuous-integration

My appveyor.yml looks like below:
environment:
matrix:
- solution_name: Src/App1.sln
- solution_name: Src/App2.sln
before_build:
- cmd: dotnet restore %solution_name%
build:
project: '%solution_name%'
publish_nuget: true
after_build:
- dotnet pack Src\App1.csproj
deploy:
- provider: NuGet
api_key:
secure: [my api key]
on:
branch: master
artifact: /.*(\.|\.s)nupkg/
artifacts:
- path: Out\
name: App1
- path: '**\*.nupkg'
It works well with one catch: it seems deploy twice during the build process. Below is part of the AppVeyor log:
Collecting artifacts...
Found artifact 'Out' matching 'Out' path
Found artifact 'Out\App1\Release\App1.6.0.3.nupkg' matching '**\*.nupkg' path
Uploading artifacts...
[1/2] App1.6.0.3.nupkg (164,127 bytes)...100%
[2/2] Out\App1\Release\App1.6.0.3.nupkg (164,127 bytes)...100%
Deploying using NuGet provider
Publishing App1.6.0.3.nupkg to https://www.nuget.org/api/v2/package...OK
Publishing App1.6.0.3.nupkg to https://www.nuget.org/api/v2/package...Skipped (A package with ID 'App1' and version '6.0.3' already exists and cannot be modified.)
No packages were pushed.
So I login NuGet.org and I can see App1.6.0.3 is published successfull. However, in the above log, the same package is published twice, hence the second publish is skipped, and end up with message "No packages we pushed." But actually there was one package pushed.
Maybe it is because I have a matrix configuration under environment section, so AppVeyor runs deploy twice? If so, how can tell AppVeyor to deploy only once?

After some experiments, I found a fix, that is removing publish_nuget: true under build section. This line will cause AppVeyor to create a nuget package, and dotnet pack Src\App1.csproj command under after_build section will create a nuget package, too. So there will be two identical .nupkg files generated in different location, and AppVeyor will find both files and push them to nuget server.
Result:
build:
project: '%solution_name%'
after_build:
- dotnet pack Src\App1.csproj

Related

Gitlab working directory not clean when using cache with CLONE_STRATEGY: none

I have a GitLab pipeline setup that has a package step to do a maven build during the tag event and a release to upload the jar to the GitLab generic package registry using curl and GitLab-release cli.
What I'm expecting to happen is a cache of the .m2 to be loaded into the package step to allow the mvn clean package to do its thing. Then archive the created jar and test results only.
The release step should begin clean with no git clone, no cache and only the jar and test results.
Instead the 'find .' shows the release step contains everything including
Git directory (.git)
Full checked out repository
.m2 cache
target (fully built as the Package step produced)
From the cache documentation (https://docs.gitlab.com/ee/ci/caching/) on GitLab it states
Archive: 'dependencies' keyword to control which job fetches the artifacts
Disable Cache uses the 'cache: []'
Why is GitLab putting so much content into the release job? The release job fails at times because its finding multiple Jar files from previous tags (IE the clean and the archiving are holding past version).
gitlab-ci.yml
variables:
MAVEN_CLI_OPTS: "-s $CI_PROJECT_DIR/.m2/settings.xml"
MAVEN_VERSION_PLUGIN_VERSION: 2.11.0
MAVEN_ARTIFACT_NAME: test-component
GIT_CLEAN_FLAGS: -ffd
PACKAGE_REGISTRY_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${MAVEN_ARTIFACT_NAME}"
cache:
key: primary
paths:
- .m2/repository
stages:
- package
- release
package:
stage: package
image: maven:latest
script:
- mvn ${MAVEN_CLI_OPTS} clean package
artifacts:
paths:
- target/*.jar
- target/surefire-reports
only:
- tags
- merge_requests
- branches
except:
- main
release:
stage: release
image: alpine:latest
cache: []
variables:
GIT_STRATEGY: none
dependencies:
- package
script:
- |
apk add curl gitlab-release-cli
find .
JAR_NAME=`basename target/${MAVEN_ARTIFACT_NAME}-${CI_COMMIT_TAG}.jar`
'curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file target/${JAR_NAME} ${PACKAGE_REGISTRY_URL}/${CI_COMMIT_TAG}/${JAR_NAME}'
release-cli create --name "Release $CI_COMMIT_TAG" --description "$TAG_MESSAGE" --tag-name ${CI_COMMIT_TAG} --assets-link "{\"name\":\"jar\",\"url\":\"${PACKAGE_REGISTRY_URL}/${CI_COMMIT_TAG}/${JAR_NAME}\"}"
only:
- tags
See the GitLab docs on GIT_STRATEGY:
A Git strategy of none also re-uses the local working copy, but skips all Git operations normally done by GitLab. GitLab Runner pre-clone scripts are also skipped, if present. This strategy could mean you need to add fetch and checkout commands to your .gitlab-ci.yml script.
It can be used for jobs that operate exclusively on artifacts, like a deployment job. Git repository data may be present, but it’s likely out of date. You should only rely on files brought into the local working copy from cache or artifacts.
So GitLab documentation is pretty clear that you should always expect the git repository to be present. When you want to work exclusively with artifacts, I you can create a new temporary directory and reference the path to the artifacts explicitly rather than relying on a totally clean working directory.

How do you import artifacts from one Bitbucket pipeline to another?

We have a complex build system, with a many to many relationship between our libraries and our applications. We put each library and application in it's own repository, and use the output of the library builds in our application builds.
On our old Jenkins server, we simply set up a custom workspace and checked out the projects into standardized relative paths so they could find each other. Post build steps assured that only successful builds copied to the central bin folder at the expected relative path.
On our Bamboo server, our repository was fetched to a Checkout Directory at the expected relative path, and we could fetch artifacts from other builds and put them in the central bin folder at the expected relative path.
Now I'm trying to set up some Bitbucket Pipelines builds, and I can't see an obvious way to do a similar thing. The working folder is set automatically by pipelines, I can't push that repository into a subfolder that is relative to other build outputs. I can create artifacts, but I can't seem to import them into other pipelines. I can create caches, but again I can't seem to import them into other pipelines.
Library bitbucket-pipelines.yml
image: mcr.microsoft.com/dotnet/sdk:5.0
pipelines:
branches:
master:
eCRF2:
- step:
name: Build and Test
caches:
- dotnetcore
- platform2
script:
- dotnet restore ./NET5/Platform2.sln
- dotnet build ./NET5/Platform2.sln --no-restore --configuration Release
artifacts:
- NET5/Platform2/bin/**
definitions:
caches:
platform2: NET5/Platform2/bin
App bitbucket-pipelines.yml
image: mcr.microsoft.com/dotnet/sdk:5.0
pipelines:
default:
- step:
name: Build and Test
caches:
- dotnetcore
- platform2
script:
- export PROJECT_NAME=./PlatformDataService.sln
- dotnet restore ${PROJECT_NAME}
- dotnet build ${PROJECT_NAME} --no-restore --configuration Release
artifacts:
- PlatformDataService/bin/**
https://support.atlassian.com/bitbucket-cloud/docs/deploy-build-artifacts-to-bitbucket-downloads/ did get me to upload a file to the Downloads section of the repository, but how do I pull it into the other pipeline?
Is there a way to solve this within bitbucket pipelines itself or do I have to get a nuget server that's available outside my VPN?

How to use npm link command in Azure pipelines

I have created SPFX library module in which there is code to be shared with multiple webparts similar to the one here. I used npm link <lib name> command to link it. It works pretty well in the local environment as well as when I deploy it manually in SharePoint online app catalog. But if I deploy it using Azure Pipelines (YAML script) it always throws and error for library not found.
I have made it sure that the library is built first and then other webparts are built in pipeline (by introducting stages) but still it doesn't find the library. Is there a way to run npm link as a pipeline task?
If the library is first built in a different stage or job, the library will not be located in the same agent machine with the other webparts.
Let's say the library is built in Stage A and the other webparts are built in Stage B. As workaround, you will need to publish the library as artifacts to azure devops server using Publish Build Artifacts task in stage A. And then download the library to the agent which builds the other webparts in Stage B using Download Build Artifacts task.
For below example:
The library is built in stage A and published to azure devops server as artifacts named library.
In Stage B, the library artifacts is downloaded from azure devops server to folder $(Build.ArtifactStagingDirectory). Then you can refer to the library by path $(Build.ArtifactStagingDirectory)/library for the following tasks in Stage B.
If multiple webparts are built in different jobs in Stage B, each job in Stage B will need to download the library artifacts, for different jobs run on different agent virtual machines.
stages:
- stage: A
jobs:
- job: Library
pool:
vmImage: "windows-latest"
steps:
...
- task: PublishBuildArtifacts#1
inputs:
PathtoPublish: {path to the library}
ArtifactName: library
- stage: B
dependsOn: A
jobs:
- job: WebParts1
pool:
vmImage: "windows-latest"
steps:
- task: DownloadBuildArtifacts#0
inputs:
downloadPath: $(Build.ArtifactStagingDirectory)
buildType: current
artifactName: library
...
- job: WebParts2
pool:
vmImage: "windows-latest"
steps:
- task: DownloadBuildArtifacts#0
inputs:
downloadPath: $(Build.ArtifactStagingDirectory)
buildType: current
artifactName: library
...
After trying the solutions posted above it still didn't work so I published it as NPM package using npm publish command. This solved the problem.
We can also use this command in YAML to automatically publish the package everytime we build but that was not required in my case so I didn't use it.

VSTS release pipeline cant find released artifact

I'm trying to setup a CI/CD without much luck. My aim is to build a .net web project trough VSTS and deploy it to a AWS Beanstalk app.
Where am I so far?
Created a vsts-ci.yml file as following:
# ASP.NET
# Build and test ASP.NET web applications.
# Add steps that publish symbols, save build artifacts, deploy, and more:
# https://learn.microsoft.com/vsts/pipelines/apps/aspnet/build-aspnet-4
pool:
vmImage: 'VS2017-Win2016'
variables:
solution: '**/*.sln'
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'
steps:
- task: NuGetToolInstaller#0
- task: NuGetCommand#2
inputs:
restoreSolution: '$(solution)'
- task: VSBuild#1
inputs:
solution: '$(solution)'
msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(Build.artifactStagingDirectory)"'
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
- task: VSTest#2
inputs:
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
And I have a build definition like below:
With this my first step build runs correctly. Btw Agent pool is Hosted VS2017.
Then I have created a release pipeline like below:
And as the Stage 1 tasks (the part that runs after artifact step), I have following:
I have hooked the build to a master branch commit, and hooked the release to a successful build, these triggerings works correctly. Though it fails. The problem is caused by not found artifact files probably because of wrong path inputs. But I don't know the correct versions.
After build finishes, it claims it created a .zip file containing the published version:
But after this, the release fails, only by saying no such file. I have tried many paths at Web Deploy Archive field, but none of them could find the zip file.
The powershell task you see, I created it to check the paths, and what they have in them, and they are mostly empty.
One interesting thing I figured is, build puts the files in D:\a\1\a but release tasks try to look into D:\a\r1\a when I suffixed the Web Deploy Archive field with $(System.defaultWorkingDirectory) and $(Build.artifactStagingDirectory).
Another odd thing is that on release Download artifact stage, it says Linked artifact count: 0. Which I would expect to be something else.
What am I doing wrong here? If someone can guide me trough, I would appreciate.
Update: I've added "Publish Artifact: drop"
When Path to publish is "$(System.DefaultWorkingDirectory)/project-2-codes.zip"
Publishing build artifacts failed with an error: Not found PathtoPublish: D:\a\r1\a\project-2-codes.zip
When Path to publish is "$(System.DefaultWorkingDirectory)"
Publishing build artifacts failed with an error: Not found PathtoPublish: D:\a\r1\a\$(Build.ArtifactStagingDirectory)
After a lot of head banging to the walls, I've found out the problem.
I was creating the build definition all wrong. I have used the default wizard thing, without noticing the custom designer (I don't think the text next to the link and the name of the link makes any sence).
And it was creating an almost empty build definition. I didn't even understood what it was doing. Now, using the visual designer I can actually select a buil definition template with all the required build tasks in it. After creating the build correctly, everything worked just nice.
Here is the build definition I came up with:
And here is the beanstalk deployment task:
You need to publish your build outputs as an artifact. Use the Publish Artifact task.

Appveyor builds for all branches instead of specified ones

We have currently three separated appveyor projects, one for each branch in our repository.
Our problem is follwing:
Appveyor ignores my filter on github branches. Everytime we make a commit to master, stage or dev it builds on all three projects instead of the single one we did make a commit to.
Each branch has a unique appveyor.yml file looking like this:
This is the appveyor.yml for dev
version: 0.0.{build}
branches:
only:
- dev
image: Visual Studio 2017
configuration: dev
before_build:
- nuget restore
build:
project: Core.Api.sln
publish_wap: true
verbosity: minimal
build_script:
- ps: .\build.ps1
after_build:
- cmd: dotnet publish src\Core.Api --output %appveyor_build_folder%\dist
test: off
artifacts:
- path: dist
name: dist.web
deploy:
...
When we make a commit, it builds on all projects. Any idea??
This happens because each project has Webhook configured on GitHub and each time someone makes a commit, each project build is triggered by webhook. Then, regardless of what branch is configured for project (that is only default branch for manual/API builds), AppVeyor reads appveyor.yml from the branch where commit was done.
Solution is to use either alternative YAML file names or alternative YAML file location.
With alternative YAML file names you can have something like appveyor-dev.yml, appveyor-stage.yml files and set specific AppVeyor project to use specific file. With alternative YAML file location is it basically the same, but in other location than repo. I personally like alternative YAML file location more because of less duplication and potential merging issues.
In both cases when webhook in say branch dev come to stage project, it still will read appveyor-dev.yml and do the right filtering.

Resources