原文链接
If you have developed CI/CD or Automation pipelines using Jenkins, you must have faced the challenge that there is a lack of one such parameter which can validate the input and show error message to user before they hit the build button. This was the headache I also experienced.
After some research and playing with different plugins, I found that I can solve this with the help of Active Choices Plugin.
Active Choices Plugin
Active Choices Plugin provides three useful parameter types which can be updated dynamically with the help of groovy script. We are going to use Active Choices Reactive Reference Parameter for our use case.
Active Choices Reactive Reference Parameter can read other input parameters and can be modified to show custom html dynamically (i.e. before clicking the build button.)
Use Case
We are going to observe the following use case here:
We need a Jenkins pipeline which takes three string parameters: EMAIL_IDS, GITHUB_REPO and GITHUB_BRANCH.
EMAIL_IDS and GITHUB_BRANCH should be validated dynamically and Build button should be invisible until all parameters are validated.
Error message shown for blank parameters
Info message when all parameters are valid
Error message when invalid inputs are given
EMAIL_IDS Validator
For validation of EMAIL_IDS field we can configure an Active Choices Reactive Reference Parameter without a name, which:
Reads EMAIL_IDS field, splits the input value on comma and validates each value agains a regex.
If EMAIL_IDs is blank, it shows a warning message for blank input in red colour and the Build button is not displayed.
If invalid Email IDs are found, it creates a list of invalid Email IDs and shows them in a warning message in red colour and the Build button is not displayed.
If all Email IDs are valid, it shows an info message in green colour.
Groovy Script
import jenkins.model.*
// a list of inavalid Email IDs
def invalid_email_ids = []
// Show error if Email IDs are blank
if(EMAIL_IDS.trim() == ""){
return """
❌ Email IDs should not be blank.
"""
}
else{
// Validate Email Ids one by one
EMAIL_IDS.split(",").each{ email_id ->
email_id = email_id.trim().toLowerCase()
if(!(email_id ==~ /^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$/)){
// Add invalid Email IDs to the list
invalid_email_ids.add(email_id)
}
}
}
if(!invalid_email_ids){
// If list is empty, show info message
return "✅ Valid Email Id(s)"
}
else{
// If list is not empty, show error message
return """
❌ Invalid Email IDs: ${invalid_email_ids.join(', ')}.
"""
}
Choice Type : Formatted HTML
Referenced parameters : EMAIL_IDS
Github Parameters Validator
For validation of Github repo and branch fields we can configure an Active Choices Reactive Reference Parameter without a name, which:
Reads GITHUB_REPO and GITHUB_BRANCH fields.
Reads GITHUB_ACCESS_TOKEN from Jenkins credential store. (GITHUB_ACCESS_TOKEN is the ID of Github token stored as Secret Text in Jenkins credential store.)
Validates GITHUB_REPO and GITHUB_BRANCH via Github API.
Shows warning in red colour if Github fields are invalid and the Build button is not displayed.
Shows info in green colour if Github fields are valid.
Groovy Script
import jenkins.model.*
// Credential ID of github token stored in Jenkins credential store
def credentialsId = 'GITHUB_ACCESS_TOKEN'
def GITHUB_ORG = '' // Replace with your organization's name
// Read token
def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
com.cloudbees.plugins.credentials.Credentials.class, Jenkins.instance, null, null ).find{
it.id == credentialsId}
def token = creds.getSecret()
// Validate using github api
def api_url = "https://api.github.com/repos/${GITHUB_ORG}/${GITHUB_REPO}/branches/${GITHUB_BRANCH}"
def get = new URL(api_url).openConnection();
get.setRequestProperty("Accept", "application/vnd.github.v3.raw")
get.setRequestProperty("Authorization", "Bearer "+token)
def getRC = get.getResponseCode();
if (getRC.equals(200)) {
// If repo and branch are valid, show info message
return "✅ Valid Branch"
}
else{
// If repo and/or branch are invalid, show error message
return """
❌ Invalid Branch, Please check GITHUB_BRANCH parameter.
"""
}
Choice Type : Formatted HTML
Referenced parameters : GITHUB_BRANCH,GITHUB_REPO
Pipeline Script
For pipelines, we can use following script to generate these parameters:
def EMAIL_VALIDATION_SCRIPT = '''import jenkins.model.*
def invalid_email_ids = []
if(EMAIL_IDS.trim() == ""){
return """
❌ Email IDs should not be blank.
"""
}
else{
EMAIL_IDS.split(",").each{ email_id ->
email_id = email_id.trim().toLowerCase()
if(!(email_id ==~ /^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$/)){
invalid_email_ids.add(email_id)
}
}
}
if(!invalid_email_ids){
return "✅ Valid Email Id(s)"
}
else{
return """
❌ Invalid Email IDs: ${invalid_email_ids.join(\', \')}.
"""
}
'''
def GITHUB_BRANCH_VALIDATION_SCRIPT = '''import jenkins.model.*
def credentialsId = \'GITHUB_ACCESS_TOKEN\'
def GITHUB_ORG = \'\'
def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
com.cloudbees.plugins.credentials.Credentials.class, Jenkins.instance, null, null ).find{
it.id == credentialsId}
def token = creds.getSecret()
def api_url = "https://api.github.com/repos/${GITHUB_ORG}/${GITHUB_REPO}/branches/${GITHUB_BRANCH}"
def get = new URL(api_url).openConnection();
get.setRequestProperty("Accept", "application/vnd.github.v3.raw")
get.setRequestProperty("Authorization", "Bearer "+token)
def getRC = get.getResponseCode();
if (getRC.equals(200)) {
return "✅ Valid Branch"
}
else{
return """
❌ Invalid Branch, Please check GITHUB_BRANCH parameter.
"""
}'''
properties(
[
parameters(
[
string(description: 'Comma separated list of Email IDs', name: 'EMAIL_IDS', trim: true),
activeChoiceHtml(choiceType: 'ET_FORMATTED_HTML', name: '', omitValueField: false, randomName: 'choice-parameter-245311171714083', referencedParameters: 'EMAIL_IDS', script: groovyScript(fallbackScript: [classpath: [], oldScript: '', sandbox: false, script: ''], script: [classpath: [], oldScript: '', sandbox: false, script: EMAIL_VALIDATION_SCRIPT])),
string(description: 'Github repository name', name: 'GITHUB_REPO', trim: true),
string(description: 'Github branch', name: 'GITHUB_BRANCH', trim: true),
activeChoiceHtml(choiceType: 'ET_FORMATTED_HTML', name: '', omitValueField: false, randomName: 'choice-parameter-245311175576333', referencedParameters: 'GITHUB_BRANCH,GITHUB_REPO', script: groovyScript(fallbackScript: [classpath: [], oldScript: '', sandbox: false, script: ''], script: [classpath: [], oldScript: '', sandbox: false, script: GITHUB_BRANCH_VALIDATION_SCRIPT]))
]
)
]
)
Conclusion
The examples shown here covers some use cases I have found challenging. We can validate any parameter with any logic using this approach.
This prevents delayed failure due to invalid parameter and saves valuable time.
原文链接 One code signing issue I commonly see, both here on DevForums and in my Day Job™ with DTS, is that the codesign command fails with errSecInternalComponent. This issue crops up in a wide variety of circumstances and the correct fix depends on the specific problem. This post is my attempt to clarify the potential causes of this error and help folks resolve it. If you have any questions or comments about this, please start a new thread, tagging it with Code Signing so that I see it. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" Resolving errSecInternalComponent errors during code signing In some circumstances the codesign command might fail with the error errSecInternalComponent. For example: % codesign -s "Apple Development" "MyTrue" MyTrue: errSecInternalComponent This typically affects folks who are signing code in a nonstandard environm...
评论
发表评论