Question about weird behavior referencing a YAML pipeline resource using a variable for the pipeline resource name - yaml

I am experiencing weird behavior with YAML variables, parameters, and Azure pipeline resource references. The following shows the original implementation that works compared to my new implementation with a single line change that fails.
Working Implementation
Template A (makes a call to template B):
- template: Templates\TemplateB.yml
serviceBuildResourceName: resourceName
Template B (uses serviceBuildResourceName param to get pipeline run information):
$projectId = '$(resources.pipeline.${{ parameters.serviceBuildResourceName }}.projectID)'
$pipelineId ='$(resources.pipeline.${{ parameters.serviceBuildResourceName }}.PipelineID)'
Template B goes on to use the values in $projectId and $pipelineId (along with other values not listed here since it is irrelevant) to successfully retrieve information about the a pipeline run from the specific pipeline resource, serviceBuildResourceName. Note that all pipeline resources are correctly defined at the beginning yaml file for the pipeline. In this implementation above, everything works perfectly.
Failing Implementation
Template A (makes a call to template B):
- template: Templates\TemplateB.yml
serviceBuildResourceName: $(ServiceBuildResourceName)
Template B (uses serviceBuildResourceName param to get pipeline run information):
$projectId = '$(resources.pipeline.${{ parameters.serviceBuildResourceName }}.projectID)'
$pipelineId ='$(resources.pipeline.${{ parameters.serviceBuildResourceName }}.PipelineID)'
Note that the only difference is the following: instead of passing the hard-coded string into the serviceBuildResourceName parameter, I pass in a variable, which has the same value as before, resourceName. The variable is defined in an earlier template as such:
- name: ServiceBuildResourceName
value: resourceName
I feel it should still work the same, but I know get the following error in my pipeline run:
WARNING: 2023-02-12 15:52:29.5071 Response body: {"$id":"1","innerException":null,"message":"The value is not an integer.
$(resources.pipeline.resourceName.PipelineID)
I know that the variable is being correctly populated since the error message above contains "resourceName" in resources.pipeline.resourceName.PipelineID, as it should.
However, for reasons unknown to me, it now throughs an error. It seems like it doesn't recognize the pipeline resource, and instead recognizes it as a string.
Any help or insight here would be greatly appreciated, thanks!

As far as I can tell, this is because of how predefined variables work in YAML. Since resources.pipeline... is a predefined variable, it gets resolved at compile time. Thus, you can't use run-time defined variables like I am doing. Instead of resolving it as a predefined variable, it will get resolved to be a string at runtime.

Related

How to set an environment variable during a Cypress test?

I am looking to re-use a particular value across multiple step definitions in my Cypress/Cucumber test.
I was thinking of using a normal variable, but the problem is that the step definitions are stored in different files.
So I am wondering if I could assign the value to an environment variable & reference that in the other file.
I was trying to do something like Cypress.env('myUsername') = 'testUser', but I get this lint error:
Cypress environment variables can be set during a test by passing in the desired value as the second argument.
Cypress.env('HOST', 'asdf');
In the documentation, env API syntax should look like something below:
- Cypress.env()
- Cypress.env(name)
- Cypress.env(name, value)
- Cypress.env(object)
In your case the following will work
Cypress.env('myUsername', 'testUser')

Cypress visit command produces error when url is a variable

I am trying to run cy.visit() which will take a variable instead of a hardcoded value as its parameter.
In my env.json file I have an environment variable called url, which I've given a value.
{
"env": {
"url": "https://somedomain.com",
}
}
In my spec file, I am trying to pass this variable when calling cy.visit(), like so:
cy.visit(Cypress.env('url'));
When running the test, I am greeted by this error
CypressError: `cy.visit()` must be called with a `url` or an `options` object containing a `url` as its 1st argument
I've searched all over internet for a solution, but it seems like I'm the only person in the world with this exact problem.
Someone knows what's wrong? Thanks!
Edit:
As pavelsaman said, my custom file was not loading. The reason behind this was I had module.exports = (on, config... defined twice in the index.js file. Maybe it will help someone in the future!
In my env.json file I have an environment variable called url, which I've given a value.
Cypress by default looks for cypress.json file, so it seems your env.json is not loaded.
You can check this default behaviour in the docs: https://docs.cypress.io/api/cypress-api/env.html and here: https://docs.cypress.io/guides/guides/environment-variables.html#Option-2-cypress-env-json
I put successfully those env varaibles in cypress.env.json, and access it like that. You probably missnamed the file or you need to the following - since it is a sub object:
cy.visit(Cypress.env('env').url);

Suppress GraphQL: Syntax Error in VS Code when using template string

FYI: There are a ton of other posts concerning GraphQL Syntax Error in VS Code. I read many of them, but did not find anything relevant to this. My apologies if I missed it in the similar questions.
Environment:
VS Code v.1.51.1
Windows 10 x64 19041
https://github.com/apollographql/apollo-tooling v.1.17.0
React Typescript Application
I have a component that uses the useQuery hook. The query is retrieved from another query and comes in via a variable typed as string In order for the useQuery to correctly use the graphql query, it has first has to be made into a DocumentNode for which I use gql from graphql-tag npm package. The resulting code snippet looks like:
...
const PREPARED_QUERY = useMemo(() => gql`${query}`, [query])
const data = useQuery(PREPARED_QUERY, queryOptions)
...
This is working code, but the Apollo GraphQL extension throws a warning on this line:
Syntax Error: Unexpected <EOF>.GraphQL: Syntax
I understand this is because it is checking the query string to ensure that it is properly formatted and it does not understand the template string "hack".
Questions:
Can this be silences with some form of ignore comment?
If not, Is there any way to form this to make this template string pass the syntax check?
Looks like a known issue with the vscode extension - without a known solution :) https://github.com/graphql/vscode-graphql/issues/137 .
Workaround
Since gql is just a function, you can call it directly, so that the extension won't try to parse it and stop complaining.
gql(query)
Explanation on why it works
If we take a look at tagged templates docs, we'll see that it's a regular function that takes the array of static string pieces as the first argument, and interpolated expressions as the remaining arguments.
So when we do
gql`some content`
it translates to the following function call:
gql(["some content"]) // a single argument, because there is no interpolations here
Also this gql function has special code inside that allows to pass a plain string as the first arg (probably to support old JS where no template tags existed)

Nesting custom resources in chef

I am trying to build a custom resource which would in turn use another of my custom resource as part of its action. The pseudo-code would look something like this
customResource A
property component_id String
action: doSomething do
component_id = 1 if component_id.nil?
node.default[component_details][component_id] = ''
customResource_b "Get me component details" do
comp_id component_id
action :get_component_details
end
Chef::log.info("See the output computed by my customResourceB")
Chef::log.info(node[component_details][component_id])
end
Thing to note:
1. The role of customResource_b is to make a PS call to a REST web service and store the JSON result in node[component_details][component_id] overriding its value. I am creating this attribute node on this resource since I know it will be used later one, hence avoiding compile time issues.
Issues I am facing:
1. When testing a simple recipe that calls this resource in chef-client, the code in the resource gets executed to the last log line and after that the call to customResource_b is made. Which is something I am not expecting to happen.
Any advice would be appreciated. I am also quite new to Chef so any design improvements are also welcome
there is no need to nest chef resources, rather use chef idompotance, guards and notification.
and as usualy, you can always use a condition to decide which cookbook\recipe to run.

AWS Create Lambda script parameters output as parameter name, not value

I am running this Octopus community script for creating or updating a lambda function.
When we hard-code values for the parameters, the script works as advertised. However, when we define variables for use in the parameters, it always injects the name of the Octopus variable instead of the value.
Such that a variable named AWS_Dash_OrderOnline_Lambda_Function_Name is read as #{AWS_Dash_OrderOnline_Lambda_Function_Name} for the value instead of the actual variable value.
What's going on and what do I need to change?
Pertinent script code is below:
# Get the parameters.
$functionName = $OctopusParameters['FunctionName']
...
Write-Output $functionName
Output:
#{AWS_Dash_OrderOnline_Lambda_Function_Name}
You'll get the variable back as the value like this if a value cannot be determined. This could be because of a typo in the name, or it could be that there is no value for the variable that matches the scope of the current deployment.
For example, you may have a value for a variable called Foo defined for Prod and not for Dev. When you run a deployment into Dev you'll get #{Foo} but in Prod you'd get the actual value.
A technique I've used is to provide an unscoped value of something like "UnscopedFoo", then if you see that value you know you've got the name entered correctly and it's a scoping issue. If you don't then the name isn't entered correctly.
If you do not properly define your variable's scope, you will get the result as indicated in the question.
Define your scope, environment, roles, channels, etc properly and your variable values will import correctly.

Resources