-
Notifications
You must be signed in to change notification settings - Fork 5.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix #3184 Compatibility with native AWS CloudFormation variable syntax #8279
Conversation
lib/classes/Variables.test.js
Outdated
readFileSyncStub.restore(); | ||
fileExistsStub.restore(); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a higher level test here because there was no test covering that ${file(...)}
is actually parsed correctly. When I changed the regex, initially the tests passed but it was a false positive: that syntax was broken. So I added that test and iterated on the regex.
Codecov Report
@@ Coverage Diff @@
## master #8279 +/- ##
==========================================
+ Coverage 88.11% 88.19% +0.07%
==========================================
Files 250 250
Lines 9365 9400 +35
==========================================
+ Hits 8252 8290 +38
+ Misses 1113 1110 -3
Continue to review full report at Codecov.
|
expect(print.serverless.cli.consoleLog.called).to.be.equal(true); | ||
expect(YAML.load(message)).to.eql(expected); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed that test: it tested that the ${self:}
syntax worked. I had a look at the git history and the rest of the project but couldn't understand why this was tested.
Either I missed something and we should bring that back + cover it with the new regex (let me know), or it's something that isn't necessary anymore and we can move forward.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call. I would add testing some of ${self: ..}
to `variables fixture as proposed in other comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mnapoli thank you ! That looks great. See my proposal on (I believe) better approach to testing. Having that set up with runServerless
, will make it really solid I believe
lib/classes/Variables.test.js
Outdated
it('should support ${file(...)} syntax', () => { | ||
// eslint-disable-next-line no-template-curly-in-string | ||
const property = '${file(~/somedir/../config.yml)}'; | ||
|
||
const expectedFileName = `${os.homedir()}/somedir/../config.yml`; | ||
const configYml = { | ||
foo: 'bar', | ||
}; | ||
const fileExistsStub = sinon.stub(serverless.utils, 'fileExistsSync').returns(true); | ||
const realpathSync = sinon.stub(fse, 'realpathSync').returns(expectedFileName); | ||
const readFileSyncStub = sinon.stub(serverless.utils, 'readFileSync').returns(configYml); | ||
|
||
return serverless.variables | ||
.populateProperty(property) | ||
.then(valueToPopulate => { | ||
expect(realpathSync).to.not.have.been.called; | ||
expect(fileExistsStub).to.have.been.calledWithMatch(expectedFileName); | ||
expect(readFileSyncStub).to.have.been.calledWithMatch(expectedFileName); | ||
expect(valueToPopulate).to.deep.equal(configYml); | ||
}) | ||
.finally(() => { | ||
realpathSync.restore(); | ||
readFileSyncStub.restore(); | ||
fileExistsStub.restore(); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @mnapoli that's a very good call! Still we configure all new tests with runServerless
(see https://github.com/serverless/serverless/tree/master/test#unit-tests) and I think this tests can also be way better expressed with that.
I propose to introduce a variables
fixture, with simple config that references real file via ${file(
variable, and other cases we want to test when covering this PR.
Then in tests we will just confirm that resolved config reflects content from imported file (no stubs needed)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh wow that new approach is a THOUSAND times better! To be honest every time I tried to contribute to the project I was struggling so much with the tests and the mocks. But this is awesome, I did struggle to get it working at first but now it feels much better, and safer.
I updated the PR, let me know if this is what you had in mind.
expect(print.serverless.cli.consoleLog.called).to.be.equal(true); | ||
expect(YAML.load(message)).to.eql(expected); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call. I would add testing some of ${self: ..}
to `variables fixture as proposed in other comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mnapoli that looks great! I've proposed just one optimization and style improvement to prepared tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's excellent! Thank you @mnapoli
Probably the There is another case that is uncovered. This is the |
Btw. in our serverless.yml templates we're using custom variableSyntax and we have our own test cases. I just want to share it as I've already collected the cases some time ago. From sls dochttps://www.serverless.com/framework/docs/providers/aws/guide/variables/
From aws Fn::Sub syntaxhttps://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html
|
Added Deprecation notice
Hi, noob question here: I tried to use ${AWS::AccountId} in my template file to inject it in an environment variable but it did not work: environment:
ACCOUNT_ID: ${AWS::AccountId} process.env.ACCOUNT_ID is equal to Am I doing something wrong? I am using serverless 2.4.0. |
I think it should be |
This is documentation of change added in serverless#8279
This is documentation of change added in serverless#8279
Update documentation for change added in serverless#8279
Closes: #3184
This PR brings support for native CloudFormation variables, such as
${AWS::Region}
or CloudFormation references (e.g.${MyS3Bucket}
). I haven't tested yet if!Sub
works correctly after this change, maybe there are additional changes to do for that.I applied the solution described in #3184 by @medikoo (change the
variableSyntax
regular expression), however I had to tune it a bit to preserve support for the${file(...)}
syntax.I tested the regex with these patterns:
I also had to add some tests to cover better some syntax. I'll add some inline comments.