Code build artifacts are not packed correctly - c#

I am using AWS Pipeline to deploy a .NET Framework application but I am stuck while trying to create the zip file for Code Deploy.
The source and build steps are passing but when trying to create the package for Code Deploy, something odd is happening.
Here is my folder structure:
Project
-Source
-Base
-CoreAPI
-Api
- bin
- scripts
- appspec.yml
- ...
-Database
- ...
-Nuget
- ...
After the build, I want to create a zip file with all files and folders within "Project\Source\Base\CoreAPI\Api"
Here is a part of the buildspec.yml which relates to artifacts:
artifacts:
files:
- '**/*'
name: "api-build-artifact"
base-directory: .\Source\Api\CoreAPI\Api
As a result code build creates a zip file with all the files and folders within "Source", basically it discards the "base-directory".
I tried some variations like these:
artifacts:
files:
- '.\Source\Base\CoreAPI\Api\**\*'
But then I get a zip with the folder structure Source\Base\CoreAPI\Api + all files and folders and obviously, Code Deploy fails because the "appspec.yml" file is not in the root folder.
Any idea what might be wrong here?

Your indentation under artifacts is wrong. Try this:
artifacts:
files:
- '**/*'
name: "api-build-artifact"
base-directory: .\Source\Api\CoreAPI\Api
discard-paths: yes
Ref:
https://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html

Related

Microsoft .NET Core 3 & Visual Studio - Linq Add Migration fails to createapphost after moving source code to new path / folder / directory

I moved from this path:
C:\Users\chris\Dropbox\repos
To this:
C:\Users\chris\source\repos
Now, when I run an (add migration),It fails with an error finding the source code.
I figured out that paths are hard-coded in the file:
Project-Folder\obj\Debug\netcoreapp3.1\project-name.csproj.FileListAbsolute.txt
I updated the paths in the file with the new path and now the add-migration command works again!

VS 2015 Publish is failing -

Hi My WEB API project is failing with these error.
Though I could build and run my project without any error.
2> CopyPipelineFiles: Copying build\native\bin\$(NativeDependenciesToolset)\$(NativeDependenciesPlatform)\$(NativeDependenciesConfiguration)\dynamic\$(ZlibCallingConvention)\zlib.dll to C:\Temp\Package\PackageTmp\build\native\bin\$(NativeDependenciesToolset)\$(NativeDependenciesPlatform)\$(NativeDependenciesConfiguration)\dynamic\$(ZlibCallingConvention)\zlib.dll.
2>C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\Web\Microsoft.Web.Publishing.targets(2991,5):
Error : Copying file build\native\bin\$(NativeDependenciesToolset)\$(NativeDependenciesPlatform)\$(NativeDependenciesConfiguration)\dynamic\$(ZlibCallingConvention)\zlib.dll to C:\Temp\Package\PackageTmp\build\native\bin\$(NativeDependenciesToolset)\$(NativeDependenciesPlatform)\$(NativeDependenciesConfiguration)\dynamic\$(ZlibCallingConvention)\zlib.dll failed. Could not find file 'build\native\bin\$(NativeDependenciesToolset)\$(NativeDependenciesPlatform)\$(NativeDependenciesConfiguration)\dynamic\
Basically it turns out to be a 264 character limit. After making a Subst to the folder source solution published correctly.

How To Set Folder Permissions in Elastic Beanstalk Using YAML File?

I have a C# Web API Elastic Beanstalk app which needs a folder outside the deployment directory that the IUSER and IIS_USERS users can write to. I've created a .config file and put this in the top level .ebextensions folder in my project. The contents are below:
commands:
0_mkdir:
command: mkdir C:\\AppFolder\\
1_set_iuser_permissions:
command: cacls C:\\AppFolder\\ /t /e /g IUser:f IIS_Users:f
However while the folder is created successfully the permissions aren't set. If anyone has any idea what I am doing wrong I would be hugely grateful. Big thanks in advance.
In the end I switched to using Json instead of YAML as, despite my YAML being validated by several online YAML testers, AWS still wouldn't accept it. It always had issues with the parameters passed to icacls. I also changed to a folder within the application App_Data folder as setting permissions on any directory external to the application didn't appear to work. So, my final configuration file is as follows:
{
"container_commands": {
"01": {
"command": "icacls \"C:/inetpub/wwwroot/AppName_deploy/App_Data/AppFolder\" /grant DefaultAppPool:(OI)(CI)F"
}
}
}
Hope this helps someone else out.
It looks like you are using invalid .net accounts (unless these are custom accounts you created). That is part of the reason why your permissions are not being set. They should be IUSR or IIS_IUSRS
Furthermore, container_commands executes after your app/server environment has been setup, but before your deployment has started. There is no other way to set permissions on files/folders within your deployment directory other than using a wpp.targets file within visual studio.
The following SO post is a good read using wpp.targets to solve your issue.
Can Web Deploy's setAcl provider be used on a sub-directory?
Place a file 01_fix_permissions.config inside .ebextensions folder.
contents:
files:
"/opt/elasticbeanstalk/hooks/appdeploy/pre/49_change_permissions.sh":
mode: "000755"
owner: root
group: root
content: |
#!/usr/bin/env bash
sudo chown -R ec2-user:ec2-user tmp/

How can I prevent bad project references?

We are using C# projects with TFS as source control and for the CI builds.
I keep finding that other developers are referencing assemblies from /Bin directories incorrectly when they should be using our /Libs folder (where we keep 3rd party assemblies)
What can I do as part of the solution build or CI build (we do also use powershell) to check and fail the build if anyone does this?
Add a custom activity to your build process template. The activity's pseudo code should look like:
Execute before the compilation phase.
Loop all new changesets containing file extensions ending with *proj.
For all *proj files, search their contents for HintPath elements containing \Bin.
If results > 0, exit build with error, listing the policy failing projects.
To complete the solution also consider enforcing a custom check-in policy for the VS clients.
Since you are using PowerShell you might as well use it for this problem; the principle is straightforward: parse all csproj files and check if the HintPath doe not contain your Bin directory. In PowerShell that is something like (I've only just begun learning PS so there might be shorter ways):
# define path to bindir (or part of it) and main source dir
$binDir = path\to\Bin
$sourceDir = path\to\sourcefiles
# fix dots and slashes (or anything that cannot be used in regex
$binDirReg = $binDir -replace '\\', '\\' -replace '\.', '\.'
# parse
$res = Get-ChildItem -Recurse -Include *.csproj -Path $sourceDir |
Select-String "HintPath>.*$binDirReg.*<"
if( $res )
{
"ERROR somebody used Bin dir instead of Lib"
}

Storing settings for a nuget package. Is there a better way?

I have a console application that is available via nuget or on it's own. It gets installed into the tools directory for the NuGet package. The application requires 3 pieces of 'configuration' information.
a database connection string
a folder path
one more configuration option (string)
Currently, I store these configuration values in a text file right next to the exe in a file called settings.js, serialized as json.
When the application first runs, if the file is not present, it creates one with default values.
I keep the settings.js file in this location so the file will get checked into source control.
My question is about maintaining the settings file across versions.
If you Update-Package via nuget, everything works great, except the new version doesn't have any settings i had configured, because there is a new folder created for the new version.
I have written a powershell script to run in init.ps1 to pull the settings from the last version of the package, and seems to work. However this feels kinda dirty and I am wondering if there is a better way to solve this problem when using nuget to deliver my application.
param($installPath, $toolsPath, $package)
Set-Alias hump (Join-Path $toolsPath hump.exe)
$sorted_list = new-object system.collections.SortedList
$parent_path = Join-Path $installPath ".."
foreach($f in Get-ChildItem $parent_path -Filter Humpback* | Foreach {$_.FullName}){
$sorted_list.Add($f,$f)
}
if($sorted_list.Count -gt 1){
$old_path = $sorted_list.Values[$sorted_list.Count - 2]
$new_path = Join-Path $installPath "tools"
$current_settings = Join-Path $new_path "settings.js"
$has_current_settings = Test-Path $current_settings
if($has_current_settings -eq $false){
$old_settings = Join-Path $old_path "tools\settings.js"
Copy-Item $old_settings $new_path
}
}
Also, init.ps1 doesn't appear to run when installing a package using the command line tool (nuget.exe). Is this expected behavior?
Can you access System.Environment.GetFolderPath? I'd just create a folder under ApplicationData special folder, and store the settings there.

Categories