Skip to content

Add upload-assets safe output to python-dataviz workflow#2911

Merged
pelikhan merged 3 commits intomainfrom
copilot/update-shared-agentic-workflow
Oct 31, 2025
Merged

Add upload-assets safe output to python-dataviz workflow#2911
pelikhan merged 3 commits intomainfrom
copilot/update-shared-agentic-workflow

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Oct 31, 2025

The python-dataviz shared workflow needed support for URL-addressable chart images in reports. The sample workflow also required simplification to demonstrate asset uploads with randomly generated data instead of requiring external data sources.

Changes

Sample Workflow (python-data-charts.md)

  • Added upload-assets safe output to enable chart publishing to orphaned git branch
  • Removed workflow_dispatch inputs (data_source, chart_type)
  • Changed from GitHub API data collection to NumPy random data generation
  • Added Phase 3 instructions for uploading charts and embedding URLs in discussion reports

Shared Workflow (python-dataviz.md)

  • Added "Including Images in Reports" section documenting the 3-step process:
    1. Generate chart with plt.savefig()
    2. Upload using upload asset tool (returns GitHub raw URL)
    3. Embed in markdown with ![](URL_FROM_UPLOAD_ASSET)

Example Usage

The AI agent now generates visualizations and embeds them directly:

## Generated Visualizations

### Chart 1: Distribution Plot
![Sample Distribution](https://raw.githubusercontent.com/owner/repo/assets/workflow-name/distribution.png)

The distribution shows...

Assets are published to assets/${{ github.workflow }} branch with default config (PNG/JPG/JPEG, 10MB max).

Original prompt

Update the pythondataviz shared agentic workflow:

  • safe output upload-asset is required to upload generated images
  • include images in report markdown

Update python sample: remove details about how to generate charts, it's already in the shared output. Generate random data and chart it. No inputs.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 2 commits October 31, 2025 23:00
- Added upload-assets to python-data-charts workflow
- Removed workflow_dispatch inputs (data_source, chart_type)
- Simplified instructions to generate random data instead of specific data sources
- Added instructions for uploading charts as assets and embedding images in reports
- Updated shared python-dataviz.md with asset upload documentation

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Update pythondataviz workflow for image uploads and reporting Add upload-assets safe output to python-dataviz workflow Oct 31, 2025
Copilot AI requested a review from pelikhan October 31, 2025 23:06
@pelikhan pelikhan marked this pull request as ready for review October 31, 2025 23:29
Copilot AI review requested due to automatic review settings October 31, 2025 23:29
@pelikhan pelikhan merged commit 08f9a1b into main Oct 31, 2025
14 checks passed
@pelikhan pelikhan deleted the copilot/update-shared-agentic-workflow branch October 31, 2025 23:29
@github-actions
Copy link
Copy Markdown
Contributor

Agentic Changeset Generator triggered by this pull request.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds URL-addressable chart image support to the python-dataviz workflow by introducing the upload-assets safe output feature. The changes simplify the sample workflow to use randomly generated data instead of external sources while enabling AI agents to embed generated visualizations directly in discussion reports.

Key changes:

  • Added upload-assets safe output configuration to publish charts to an orphaned git branch
  • Simplified sample workflow to generate random NumPy data instead of requiring GitHub API or external data sources
  • Added comprehensive documentation for the 3-step asset upload process in shared workflow

Reviewed Changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 6 comments.

File Description
.github/workflows/shared/python-dataviz.md Added "Including Images in Reports" documentation section explaining asset upload workflow
.github/workflows/python-data-charts.md Simplified to use random data generation, added upload-assets safe output, removed workflow_dispatch inputs
.github/workflows/python-data-charts.lock.yml Generated workflow YAML with asset upload job, environment variables, and updated permissions

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}
if (hasChanges) {
const commitMessage = `[skip-ci] Add ${uploadCount} asset(s)`;
await exec.exec(`git`, [`commit`, `-m`, `"${commitMessage}"`]);
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The commit message is double-quoted in the exec call, but the template literal already contains the message. This will result in the commit message being wrapped in literal quote characters. Remove the quotes from the -m parameter: await exec.exec('git', ['commit', '-m', commitMessage]);

Suggested change
await exec.exec(`git`, [`commit`, `-m`, `"${commitMessage}"`]);
await exec.exec(`git`, [`commit`, `-m`, commitMessage]);

Copilot uses AI. Check for mistakes.
Comment on lines +4492 to +4499
await exec.exec(`git rev-parse --verify origin/${normalizedBranchName}`);
await exec.exec(`git checkout -B ${normalizedBranchName} origin/${normalizedBranchName}`);
core.info(`Checked out existing branch from origin: ${normalizedBranchName}`);
} catch (originError) {
core.info(`Creating new orphaned branch: ${normalizedBranchName}`);
await exec.exec(`git checkout --orphan ${normalizedBranchName}`);
await exec.exec(`git rm -rf .`);
await exec.exec(`git clean -fdx`);
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using template literals for shell commands without proper escaping can be vulnerable to injection if normalizedBranchName contains special characters. While normalizeBranchName() sanitizes the input, explicitly passing branch names as separate arguments is safer: await exec.exec('git', ['rev-parse', '--verify', origin/${normalizedBranchName}]);

Suggested change
await exec.exec(`git rev-parse --verify origin/${normalizedBranchName}`);
await exec.exec(`git checkout -B ${normalizedBranchName} origin/${normalizedBranchName}`);
core.info(`Checked out existing branch from origin: ${normalizedBranchName}`);
} catch (originError) {
core.info(`Creating new orphaned branch: ${normalizedBranchName}`);
await exec.exec(`git checkout --orphan ${normalizedBranchName}`);
await exec.exec(`git rm -rf .`);
await exec.exec(`git clean -fdx`);
await exec.exec('git', ['rev-parse', '--verify', `origin/${normalizedBranchName}`]);
await exec.exec('git', ['checkout', '-B', normalizedBranchName, `origin/${normalizedBranchName}`]);
core.info(`Checked out existing branch from origin: ${normalizedBranchName}`);
} catch (originError) {
core.info(`Creating new orphaned branch: ${normalizedBranchName}`);
await exec.exec('git', ['checkout', '--orphan', normalizedBranchName]);
await exec.exec('git', ['rm', '-rf', '.']);
await exec.exec('git', ['clean', '-fdx']);

Copilot uses AI. Check for mistakes.
continue;
}
fs.copyFileSync(assetSourcePath, targetFileName);
await exec.exec(`git add "${targetFileName}"`);
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using template literals with quoted filenames in shell commands is error-prone. Pass the filename as a separate argument to avoid issues with special characters: await exec.exec('git', ['add', targetFileName]);

Suggested change
await exec.exec(`git add "${targetFileName}"`);
await exec.exec('git', ['add', targetFileName]);

Copilot uses AI. Check for mistakes.
Comment on lines +4497 to +4499
await exec.exec(`git checkout --orphan ${normalizedBranchName}`);
await exec.exec(`git rm -rf .`);
await exec.exec(`git clean -fdx`);
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These git commands use template literals without proper argument separation. Use array syntax consistently: await exec.exec('git', ['checkout', '--orphan', normalizedBranchName]);, await exec.exec('git', ['rm', '-rf', '.']);, and await exec.exec('git', ['clean', '-fdx']);

Suggested change
await exec.exec(`git checkout --orphan ${normalizedBranchName}`);
await exec.exec(`git rm -rf .`);
await exec.exec(`git clean -fdx`);
await exec.exec('git', ['checkout', '--orphan', normalizedBranchName]);
await exec.exec('git', ['rm', '-rf', '.']);
await exec.exec('git', ['clean', '-fdx']);

Copilot uses AI. Check for mistakes.
Comment on lines +4492 to +4499
await exec.exec(`git rev-parse --verify origin/${normalizedBranchName}`);
await exec.exec(`git checkout -B ${normalizedBranchName} origin/${normalizedBranchName}`);
core.info(`Checked out existing branch from origin: ${normalizedBranchName}`);
} catch (originError) {
core.info(`Creating new orphaned branch: ${normalizedBranchName}`);
await exec.exec(`git checkout --orphan ${normalizedBranchName}`);
await exec.exec(`git rm -rf .`);
await exec.exec(`git clean -fdx`);
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use array argument syntax for git commands to avoid shell injection risks: await exec.exec('git', ['checkout', '-B', normalizedBranchName, origin/${normalizedBranchName}]);

Suggested change
await exec.exec(`git rev-parse --verify origin/${normalizedBranchName}`);
await exec.exec(`git checkout -B ${normalizedBranchName} origin/${normalizedBranchName}`);
core.info(`Checked out existing branch from origin: ${normalizedBranchName}`);
} catch (originError) {
core.info(`Creating new orphaned branch: ${normalizedBranchName}`);
await exec.exec(`git checkout --orphan ${normalizedBranchName}`);
await exec.exec(`git rm -rf .`);
await exec.exec(`git clean -fdx`);
await exec.exec('git', ['rev-parse', '--verify', `origin/${normalizedBranchName}`]);
await exec.exec('git', ['checkout', '-B', normalizedBranchName, `origin/${normalizedBranchName}`]);
core.info(`Checked out existing branch from origin: ${normalizedBranchName}`);
} catch (originError) {
core.info(`Creating new orphaned branch: ${normalizedBranchName}`);
await exec.exec('git', ['checkout', '--orphan', normalizedBranchName]);
await exec.exec('git', ['rm', '-rf', '.']);
await exec.exec('git', ['clean', '-fdx']);

Copilot uses AI. Check for mistakes.
if (isStaged) {
core.summary.addRaw("## Staged Asset Publication");
} else {
await exec.exec(`git push origin ${normalizedBranchName}`);
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use array argument syntax for the git push command: await exec.exec('git', ['push', 'origin', normalizedBranchName]);

Suggested change
await exec.exec(`git push origin ${normalizedBranchName}`);
await exec.exec('git', ['push', 'origin', normalizedBranchName]);

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants