If you are managing package in the app exchange, you probably using the LMA application for some of your activities. If your company is big enough, then you also probably using other tool for managing your features/bugs.
However in my case I was needed quick and simple solution to start with so I figure if the packages/versions are already in Salesforce LMA, why shouldn't I keep everything in Salesforce for start?
My needs were quite basic: place to store and monitor all the features/bugs and an option to create release note with list of changes.
The first task was very easy as Salesforce already has standard object that fit into it - ChangeRequest. I enriched this object with some custom fields and some picklist values that match my needs, like
Estimation (in hours)
Resolution (for bugs)
Release Note (text that I would like to be shown for customer in release note)
Package Version (lookup to package version)
Obviously, the package being created only after we complete the development and upload all the files. To overcome it I created also text field 'Planned Version', and might use later some automation tool to link the items to the package version when the version being created.
Next step is to be able to generate PDF for package version with all its Change Requests.
For that I was needed to use Visualforce page (yet, LWC doesn't support such feature).
- Apex controller for retrieving the data
- Page that render as PDF
- Custom button in License Version that open the page
public with sharing class GenerateReleaseNoteController{ public sfLma__Package_Version__c packageVersion {get; set;} public List<ChangeRequest> changeRequestList {get; set;} public String installationURL {get; set;} public string logURL {get; set;} public GenerateReleaseNoteController(ApexPages.StandardController sc){ Id licenseVersionId = sc.getRecord().Id; installationURL = 'https://login.salesforce.com/packaging/installPackage.apexp?p0=' + licenseVersionId; logURL = '/resource/logo'; packageVersion = [ SELECT Id,sfLma__Version__c,sfLma__Release_Date__c,sfLma__Package__r.Name FROM sfLma__Package_Version__c WHERE Id = :licenseVersionId]; changeRequestList = [ SELECT Id,Release_Note__c,Subject,Category FROM ChangeRequest WHERE Package_Version__c =:licenseVersionId Order by Category]; } }
<apex:page standardController="sfLma__Package_Version__c" extensions="GenerateReleaseNoteController" applyBodyTag="false" renderAs="pdf"> <head> <style> @page { size: A4; margin: 42mm 7mm 7mm 7mm; @top-right{ content : element(header); } } .header { position : running(header); margin: 0.5cm 0cm 0cm 1cm; } </style> </head> <body> <div class="header"> <table style="width:100%;"> <td> <h2>Package: {!packageVersion.sfLma__Package__r.Name}<br/></h2> <a href="{!installationURL}">Version: {!packageVersion.sfLma__Version__c}</a><br/> Relase Date: <apex:outputText value="{0, date, dd/MM/yyyy}"> <apex:param value="{!packageVersion.sfLma__Release_Date__c}" /> </apex:outputText> </td> <td> <div style="text-align: right;"> <apex:image url="{!logURL}" width="200px" height="100px"/> </div> </td> </table> </div> <u>List of Changes:</u><br/><br/> <table style="border: 1px solid black;border-collapse: collapse;"> <thead> <tr style="border: 1px solid black;border-collapse: collapse;"> <th style="border: 1px solid black;border-collapse: collapse; text-align:center;">Title</th> <th style="border: 1px solid black;border-collapse: collapse; text-align:center;">Category</th> <th style="border: 1px solid black;border-collapse: collapse; text-align:center;">Details</th> </tr> </thead> <tbody> <apex:repeat value="{!changeRequestList}" var="cr"> <tr style="border: 1px solid black;border-collapse: collapse;"> <td style="border: 1px solid black;border-collapse: collapse;">{!cr.Subject}</td> <td style="border: 1px solid black;border-collapse: collapse;">{!cr.Category}</td> <td style="border: 1px solid black;border-collapse: collapse;"><apex:outputField value="{!cr.Release_Note__c}"/> </td> </tr> </apex:repeat> </tbody> </table> </body> </apex:page>