Skip to content
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

WikiUpdaterTask@2 ##[error]TypeError: contents.replace is not a function #1569

Closed
scrocquesel-ml150 opened this issue Nov 24, 2023 · 6 comments · Fixed by #1571
Closed

WikiUpdaterTask@2 ##[error]TypeError: contents.replace is not a function #1569

scrocquesel-ml150 opened this issue Nov 24, 2023 · 6 comments · Fixed by #1571
Assignees

Comments

@scrocquesel-ml150
Copy link

Azure DevOps Extensions

WIKI Updater

Platform

Azure DevOps Services

Azure DevOps Server (TFS) Version

No response

Extension Version

2.8.3

Describe the bug

I have a pipeline that chain XplatGenerateRelease and WikiUpdater on a ubuntu-latest agent

The first task did produce a content in the outputfile (i can echo its content in a script task in between.)

It happens with or without the target file exists in the wiki repo.

Repo Steps

The yaml pipeline is

- task: richardfennellBM.BM-VSTS-XplatGenerateReleaseNotes.XplatGenerate-Release-Notes.XplatGenerateReleaseNotes@4
  displayName: "Generate Release Notes based on Release Comparison API"
  inputs:
    outputfile: "$(System.DefaultWorkingDirectory)/releasenotes.md"
- task: richardfennellBM.BM-VSTS-WIKIUpdater-Tasks.WikiUpdaterTask.WikiUpdaterTask@2
  displayName: "Generate Wiki page"
  inputs:
    repo: "$(WIKI_REPO)"
    useAgentToken: true
    filename: "${{ parameters.ReleaseNoteFileName }}"
    dataIsFile: true
    replaceFile: false
    appendToFile: false
    sourceFile : $(System.DefaultWorkingDirectory)/releasenotes.md
    message: Updated
    gitname: "****"
    gitemail: "****"
    trimLeadingSpecialChar: true
    fixLineFeeds: false
    insertLinefeed: true
    injecttoc: true
    localpath: "$(System.DefaultWorkingDirectory)/repo"

Expected Behavior

No error or a proper error message to help fix the sourcefile or the changelog file.

Logging Information

Variable: Repo [https://******/zzz_test]
Variable: Filename [CHANGELOG.md]
Variable: Contents [undefined]
Variable: Commit Message [Updated]
Variable: Git Username [******]
Variable: Git Email [[******]]
Variable: Use Agent Token [true]
Variable: Replace File [false]
Variable: Append to File [false]
Variable: Username [undefined]
Variable: Password [*****]
Variable: LocalPath [/home/vsts/work/1/s/repo]
Variable: Data Is File [true]
Variable: SourceFile [/home/vsts/work/1/s/releasenotes.md]
Variable: Tag Repo [false]
Variable: Tag [undefined]
Variable: Branch [undefined]
Variable: InjectExtraHeader [false]
Variable: SslBackend [undefined]
Variable: Retries [5]
Variable: trimLeadingSpecialChar [true]
Variable: fixLineFeeds [false]
Variable: fixSpaces [false]
Variable: insertLinefeed [true]
Variable: updateOrderFile [false]
Variable: prependEntryToOrderFile [false]
Variable: orderFilePath [undefined]
Variable: injecttoc [true]
Variable: mode [Pull]
Using OAUTH Agent Token, overriding username and password
The provided repo URL is https://******/zzz_test
The protocol is https
The provided repo URL is https://******/zzz_test
Removing leading http:// or https:// block
Removing leading username@ block
Trimmed the URL to ******/zzz_test
URL used https://buildagent:***@******/zzz_test
Cleaned /home/vsts/work/1/s/repo
Cloned ******/zzz_test to /home/vsts/work/1/s/repo
Set GIT values in /home/vsts/work/1/s/repo
No sub-directory passed change to /home/vsts/work/1/s/repo
Git Pull, prior to local commits, in case of post clone updates to the repo from other users
Working file name is CHANGELOG.md
##[debug]Replacing old [[_TOC_]] with a new one at the top of the pre-pended content
##[debug]Appending new content after [[_TOC_]]
##[error]TypeError: contents.replace is not a function
##[debug]Processed: ##vso[task.issue type=error;]TypeError: contents.replace is not a function
##[debug]task result: Failed
##[error]TypeError: contents.replace is not a function
##[debug]Processed: ##vso[task.issue type=error;]TypeError: contents.replace is not a function
##[debug]Processed: ##vso[task.complete result=Failed;]TypeError: contents.replace is not a function
Finishing: Generate Wiki page
rfennell added a commit that referenced this issue Nov 25, 2023
rfennell added a commit that referenced this issue Nov 25, 2023
* Add a Codespaces defintion with sensible extensions
* Add more logging on content loading a null check on the content string
#1569
@rfennell
Copy link
Owner

That error points to the fact that the contents object is null, either no content was passed as a string, or the content loaded from the source file is null. But the tests you have done would point to this not being the case.

I have added extra logging and a null check on the contents variable in 2.9.x, can you retest with that.

@scrocquesel-ml150
Copy link
Author

Hello,

I do have the extra log Reading file /home/vsts/work/1/s/releasenotes.md but still the same error. could it be that contents is non null but not a string ?

@scrocquesel-ml150
Copy link
Author

Hello,

I do have the extra log Reading file /home/vsts/work/1/s/releasenotes.md but still the same error. could it be that contents is non null but not a string ?

May have changed in newer version of nodejs, but the documentation of latest version says "If the encoding option is specified then this function returns a string. Otherwise it returns a buffer."

@rfennell
Copy link
Owner

All my Node based tasks support Node10 and Node 16 and have done so since December 2022. So unless you are using a private agent I don't think the Node version is the issue.

As you are using the dataIsFile=true and fixLineFeeds=false properties the code to load your content should be loaded with a simple contents = fs.readFileSync(sourceFile);

if (dataIsFile === true) {
    if (fs.existsSync(sourceFile)) {
        logInfo(`Reading file ${sourceFile}`);
        if (fixLineFeeds) {
            contents = fs.readFileSync(sourceFile, "utf8");
        } else {
           contents = fs.readFileSync(sourceFile);
    }
} else {
    // we do this late copy so that we can use the same property for different encodings with a type clash
    logInfo(`Using contents string directly input`);
    contents = contentsInput;
}

The error message you report can only appear if you have the appendToFile=false. So what happens if this is set to `true' - does content appear?

@scrocquesel-ml150
Copy link
Author

All my Node based tasks support Node10 and Node 16 and have done so since December 2022. So unless you are using a private agent I don't think the Node version is the issue.

As you are using the dataIsFile=true and fixLineFeeds=false properties the code to load your content should be loaded with a simple contents = fs.readFileSync(sourceFile);

if (dataIsFile === true) {
    if (fs.existsSync(sourceFile)) {
        logInfo(`Reading file ${sourceFile}`);
        if (fixLineFeeds) {
            contents = fs.readFileSync(sourceFile, "utf8");
        } else {
           contents = fs.readFileSync(sourceFile);
    }
} else {
    // we do this late copy so that we can use the same property for different encodings with a type clash
    logInfo(`Using contents string directly input`);
    contents = contentsInput;
}

The error message you report can only appear if you have the appendToFile=false. So what happens if this is set to `true' - does content appear?

I'm using public Azure DevOps agents with ubuntu-latest image. I set fixLineFeeds=true and it fixed the issue as expected because as the doc says, when the encoding is passed to readFileSync, the result is a string not a buffer.

I disable all parameters that can modify the file down to

##[debug]Writing new content
##[error]TypeError: contents.replace is not a function

Then, I set appendToFile=true but it seems to fail with the same error in FixedFormatOfNewContent.

I cannot find a path where the contents is left untouched and simply passed to a write function that would, I guess, accept the buffer object as is.

@rfennell
Copy link
Owner

Thanks @scrocquesel-ml150 for isolating the problem so well.

I think after testing the simplest option is to just .tostring() the buffer. Version 2.10.x is being published now with this change.

Stan-Stani pushed a commit to Stan-Stani/AzurePipelines that referenced this issue Dec 5, 2023
* Add a Codespaces defintion with sensible extensions
* Add more logging on content loading a null check on the content string
rfennell#1569
Stan-Stani pushed a commit to Stan-Stani/AzurePipelines that referenced this issue Dec 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants