I create a couple workflows in the .github/workflows folder of my repository to experiment with GitHub Actions. I have since learned quite a bit and deleted said "experimental" workflows from my repo. After deleting the "experimental" workflow yaml files and committing the deletions, when I go to the Actions tab of my repository I STILL see the workflows that I have since deleted.
I see no option to delete and start from scratch?! Is this not possible? Is it maybe possible through GitHub API? Hmm.
As of July 7, 2020, you can now delete the results of individual workflow runs. To do this, navigate to your workflow, find the workflow run that you want to delete, and select the "..." menu. In this menu, select "Delete workflow run".
The workflow run and its logs will be removed.
Currently, you must do this for each workflow run individually.
edit: As of 2021 Feb it seems that after all workflow runs are deleted
the workflow it self disappears. One comment below also seems to confirm this.
It doesn't seem that there is currently a way to delete those workflows - this makes no sense - but it appears that once one makes the mistake of creating one they are stuck with it forever. The only solution so far I found is to disable these workflows.
So if I go to the Actions tab (edit the url to match your repo), I can then click on a workflow and disable it via [...] in the right top corner of that tab as in the snapshot below:
To delete all workflow results at once
To delete the records here is the solution I found here with slight modifications from the original:
user=GH_USERNAME repo=REPO_NAME; gh api repos/$user/$repo/actions/runs \
--paginate -q '.workflow_runs[] | select(.head_branch != "master") | "\(.id)"' | \
xargs -n1 -I % gh api repos/$user/$repo/actions/runs/% -X DELETE
Replace GH_USERNAME and REPO_NAME with the desired github username and repo name correspondingly.
This will delete all the old workflows that aren't on the master branch. You can further tweak this to do what you need.
Prerequisites:
You will find the latest gh version here.
Notes:
You may have to gh auth login if this is your first time using it
You may further change the command to gh api --silent if you prefer not to see the verbose output.
For the final xargs part of the command chain - the original used
-J instead of -I, which is not supported by GNU xargs. -J
results in a single command, and -I will execute the command for
each records, so it's a bit slower.
Thank you to the OP on the community forum for sharing this in first place.
Here's a few commands to quickly clean up your workflows.
You'll need the xargs, gh and jq CLI tools.
Depending on how many runs you have you'll have to execute the delete step multiple times because the GH API endpoints are paginated.
OWNER=<your user/org name>
REPO=<repo name>
# list workflows
gh api -X GET /repos/$OWNER/$REPO/actions/workflows | jq '.workflows[] | .name,.id'
# copy the ID of the workflow you want to clear and set it
WORKFLOW_ID=<workflow id>
# list runs
gh api -X GET /repos/$OWNER/$REPO/actions/workflows/$WORKFLOW_ID/runs | jq '.workflow_runs[] | .id'
# delete runs (you'll have to run this multiple times if there's many because of pagination)
gh api -X GET /repos/$OWNER/$REPO/actions/workflows/$WORKFLOW_ID/runs | jq '.workflow_runs[] | .id' | xargs -I{} gh api -X DELETE /repos/$OWNER/$REPO/actions/runs/{}
Based on the #Giampaolo RodolĂ answer (which worked for me), I created this simple shell script that does the job.
Disable the workflow you want to delete (via Github console) before executing this script.
org=<your org>
repo=<your repo>
# Get workflow IDs with status "disabled_manually"
workflow_ids=($(gh api repos/$org/$repo/actions/workflows | jq '.workflows[] | select(.["state"] | contains("disabled_manually")) | .id'))
for workflow_id in "${workflow_ids[#]}"
do
echo "Listing runs for the workflow ID $workflow_id"
run_ids=( $(gh api repos/$org/$repo/actions/workflows/$workflow_id/runs --paginate | jq '.workflow_runs[].id') )
for run_id in "${run_ids[#]}"
do
echo "Deleting Run ID $run_id"
gh api repos/$org/$repo/actions/runs/$run_id -X DELETE >/dev/null
done
done
Outcome:
Listing runs for the workflow ID 5261185
Deleting Run ID 507553125
Deleting Run ID 507548002
Listing runs for the workflow ID 5261568
Deleting Run ID 525274011
Deleting Run ID 525264327
Deleting Run ID 525247443
Ensure to have Github client installed and required token permissions in Github.
I managed to fix this (currently not possible via UI) by using "gh" CLI tool and reading REST API docs.
First, get all your workflows (these are the ones shown in the web UI -> Actions -> left column):
$ gh api repos/$YOUR_USER/$YOUR_REPO/actions/workflows
{
"total_count": 2,
"workflows": [
{
"id": 3611607,
"name": "FreeBSD",
...
},
{
"id": 4336318,
"name": "MacOS",
...
}
]
}
Use the ID of the workflow you want to delete (say 3611607) to get all of its individual runs:
$ gh api repos/$YOUR_USER/$YOUR_REPO/actions/workflows/3611607/runs
{
"total_count": 17,
"workflow_runs": [
{
"id": 363876785,
"name": "FreeBSD",
...
},
{
"id": 363876786,
"name": "FreeBSD",
...
},
{
"id": 363876787,
"name": "FreeBSD",
...
},
}
For each run id (let's say 363876785), delete it with:
$ gh api repos/$YOUR_USER/$YOUR_REPO/actions/runs/363876785 -X DELETE
After this, the undeletable Action in the left column of the web UI should disappear.
Delete all runs from a certain workflow
An improved version of #Sheece Gardazi's answer that supports selecting a certain workflow:
export OWNER="my-user"
export REPOSITORY="my-repo"
export WORKFLOW="My Workflow"
gh api -X GET /repos/$OWNER/$REPOSITORY/actions/runs --paginate \
| jq '.workflow_runs[] | select(.name == '\"$WORKFLOW\"') | .id' \
| xargs -t -I{} gh api -X DELETE /repos/$OWNER/$REPOSITORY/actions/runs/{}
(The -t option to xargs prints each workflow run deletion request to the terminal.)
It requires GitHub CLI:
brew install gh
gh auth login
and jq:
brew install jq
Delete all jobs belonged to your workflow and your workflow will be gone
P/s: in the case you have thousand of jobs to delete, then using API is a good way to go with: https://docs.github.com/en/rest/reference/actions#workflow-runs
Until GitHub implements a "Delete all workflow runs", you have to rely on the API. With the CLI tools gh and jq installed on your workstation, you can run the following commands to delete all runs of that workflow. Once all runs are removed, it won't show up anymore in the UI.
cd /path/to/your/repo
gh workflow list # Pick-up the workflow ID for which you want to delete all runs
WORKFLOW_ID=<the workflow id> # Change this line!
# List last 10 runs of the workflow you picked to double check the id
gh run list -L 10 -w $WORKFLOW_ID
# Some set up
REPO_INFO=$(gh repo view --json name,owner)
REPO_FULL_NAME="$(echo $REPO_INFO | jq '.owner.login' -r)/$(echo $REPO_INFO | jq '.name' -r)"
# Ready? Let's delete some runs!
gh api -X GET "/repos/$REPO_FULL_NAME/actions/workflows/$WORKFLOW_ID/runs?per_page=100" | jq '.workflow_runs[] | .id' -r | xargs -t -I{} gh api --silent -X DELETE /repos/$REPO_FULL_NAME/actions/runs/{}
The last command will delete the last 100 runs (limit from GitHub API). If you have more, run it multiple times to delete all.
Following to the Github Actions document: https://docs.github.com/en/actions/managing-workflow-runs/deleting-a-workflow-run
It should be easy to delete a workflow which you don't need any more, like showing in this image
If you don't see that delete option but the disable workflow instead, then it's because that workflow still have some workflow runs.
You need to delete those workflow runs and then the delete option will appears :)
And a PowerShell implementation (thanks to the other respondents),
which also requires the gh cli.
$user = "your user"
$repo = "repo"
(gh api repos/$user/$repo/actions/runs | ConvertFrom-Json).workflow_runs |
%{ $_.id } |
%{ gh api repos/$user/$repo/actions/runs/$_ -X DELETE }
Re-run the "one-liner" until you have no more; it currently pages to 30 results.
I had 600+ actions that I wanted deleted so there were multiple pages. I had to run the command in for loop:
# install following packages
sudo snap install jq gh
# To authenticate github cli
gh auth login
# for reference path to your code repository: https://github.com/$OWNER/$REPOSITORY
export OWNER=<OWNER_NAME/ORGANIZATIONS_NAME>
export REPOSITORY=<REPOSITORY_NAME>
# repeat command 30 times, if there are 30 pages of workflow history
for i in {1..30}; do gh api -X GET /repos/$OWNER/$REPOSITORY/actions/runs | jq '.workflow_runs[] | .id' | xargs -I{} gh api -X DELETE /repos/$OWNER/$REPOSITORY/actions/runs/{}; done
I wasn't able to delete the workflow inspite of all the answers in this post.. What worked for me was that I first authenticated myself using "gh auth login" and the used the below command to get the details of the workflow that you want delete. If you do not know the workflow id, then just run "gh api repos/$org/$repo/actions/workflows/" to see all the workflows. Once you run this, you will know the branch where you need to delete the workflow from. In our case, the work flow existed in the "develop" branch. You can see this in the "html_url". Once I deleted the workflow file from the develop branch, the workflow vanished from everywhere. Also, when you run the "gh api repos/$org/$repo/actions/workflows/$workflow_id", you will notice that the state will be changed to "deleted".
$> gh api repos/$org/$repo/actions/workflows/$workflow_id
{
"id": 6,
"node_id": "blah",
"name": "Run Unit Tests",
"path": ".github/workflows/unittests.yml",
"state": "active",
"created_at": "2021-05-15T00:25:19.000-07:00",
"updated_at": "2022-03-10T13:02:43.000-08:00",
"url": "blah",
"html_url": "https://company-name/workspace/project/blob/develop/.github/workflows/unittests.yml",
"badge_url": "blah"
}
For anyone wondering, deleting the workflow.yml files within .github/workflows works BUT you need to make sure it is deleted in all branches. If master/main still has the workflow files then GitHub will hold onto them.
It should be automatically be removed once you remove all related workflow runs.
Deleting the workflows runs via the CLI was only part of the solution in my case.
GitHub still refused to show any workflows I tried to add again afterwards.
I solved it by using the "New workflow" button in GH and to create a workflow from template.
I pasted the content of my original YML file and renamed the file so that everything looked like before.
Lastly, I committed via web - and GitHub showed again my workflow.
Here is another option to delete all logs from a Github actions workflow automatically, using Ritchie CLI.
All you need to do is:
run rit github delete workflow-logs
inform your github username and token
inform the repo owner and name
select the repo workflow to clean
An example can be seen here. Note that you need to import this repository using the Ritchie CLI tool for the command to work.
Install the Ritchie CLI: https://docs.ritchiecli.io/
Run rit add repo
? Select your provider: Github
? Repository name: formulas-github
? Repository URL: https://github.com/GuillaumeFalourd/formulas-github
? Is a private repository? no
? Select a tag version: {latest}
? Set the priority: 1
Run rit set formula-runner
? Select a default formula run type: docker
The default formula runner has been successfully configured!
Start Docker Desktop
Go to https://github.com/settings/tokens, add generate a GitHub Personal Access Token (use the "workflow" scope)
Run rit github delete workflow-logs
Enter your GitHub username, GitHub token, GitHub owner, GitHub repository name and select the workflow for which you want the runs to be deleted 🙌
Revoke your PAT
I created this command line tool to conveniently select multiple entries and delete them together from a navigable list:
https://github.com/jv-k/delete-workflow-runs
I made some minor adjustments to #david-miguel's answer which offloads the filtering to github's api instead of doing it locally.
#!/bin/sh
OWNER="user-name|org-name"
REPOSITORY="repository-name"
WORKFLOW="workflow-human-friendly-name"
gh run list --repo "$OWNER/$REPOSITORY" -w "$WORKFLOW" --json databaseId \
| jq '.[].databaseId' \
| xargs -I{} gh api -X DELETE /repos/$OWNER/$REPOSITORY/actions/runs/{}
I did find a way of doing this. You can go to .github/workflows or wherever your workflow is set and then commit deleting of the file(workflow file) which will finally delete it.
If you want to delete multiple workflow runs, you should use the GitHub Action API to get the run ids you want to delete, then send DELETE request with a header containing personal access token to delete the workflow run.
Try this python script to delete all workflow runs.
https://github.com/wh201906/garage/blob/master/Python/DeleteGithubAction/delete.py
It uses grequests to make multi requests at once, and this script doesn't require gh and jq.
For the people who deleted the workflow and can't delete the workflow run (404) ?
After finding this thread, i still did spent quite some time to make my workflows run fade away...
The answer provided by #ribeiro is correct, however for people that have DELETED their workflows, they won't be able to delete the runs, it will resolve into a 404!
How to delete workflows run that doesn't have workflows anymore
I've tried many things, in the end, only this worked for me:
For each workflows you deleted, create the yml file with the same name that the previous one(filename.yml and the name property in the workflow must be the same as the previous one). This way github will see them as 'existing'.
Create a .sh file and input the following (i will use the answer provided by Ribeiro, however, i will remove the state filter because i wish to delete them all)
OWNER="aOwner"
REPO="aRepo"
workflow_ids=($(gh api repos/$OWNER/$REPO/actions/workflows | jq '.workflows[] | .id'))
for workflow_id in "${workflow_ids[#]}"
do
echo "Listing runs for the workflow ID $workflow_id"
run_ids=( $(gh api repos/$OWNER/$REPO/actions/workflows/$workflow_id/runs --paginate | jq '.workflow_runs[].id') )
for run_id in "${run_ids[#]}"
do
echo "Deleting Run ID $run_id"
gh api repos/$OWNER/$REPO/actions/runs/$run_id -X DELETE >/dev/null
done
done
Run the sh file. You should see workflows run deleted (it does take some times tho)
Update 1/3/2023:
I found something new, if I add test.yml back, the history will be back.
To "truly" delete the workflow history, please refer to other answers.
As of Dec 31, 2022, assume you have a workflow .github/workflows/test.yml.
Once you delete this workflow file and merge into main branch, the workflow on the side menu plus all workflow run history will be gone.
You can verify by manually go to the old workflow link https://github.com/[username]/[repo]/actions/workflows/test.yml
This is the current result.
Here is an answer that just uses the GitHub CLI (you need to install and authenticate re: https://github.com/cli/cli#installation) and awk:
OWNER="repoOwner"
REPO="repoName"
gh run list --repo <[HOST/]OWNER/REPO> -workflow <string> | \
awk -F '\t' '{ if ($2 == "failure") { print $7 } }' | \
while read id; do gh api repos/$OWNER/$REPO/runs/$id -X DELETE; done
Remove the workflow file from the default branch.
Delete the workflow runs:
owner=hello-seer
repo=stylelab
workflow=lint.yml
gh api repos/"$owner"/"$repo"/actions/workflows/"$workflow"/runs --paginate -q '.workflow_runs[] | .id' | while read -r id; do
echo "$id"
gh api -X DELETE repos/"$owner"/"$repo"/actions/runs/"$id"
done
Update your local branch from to sync with master , then delete the github/workflows.
Commit and push your changes .
Wokflow should be deleted in master
Your workflows are *.yml files saved in your repo in the folder /.github/workflows/
Just delete them!
I tried deleting yml file from this location .github/workflows/ and it worked like a charm.
you can delete the file from the Code tab in github as it was added as a normal commit
click on the file and then click delete icon:
Im currently trying to figure out how to deploy an gitlab project automatically using ci. I managed to run the building stage successfully, but im unsure how to retrieve and push those builds to the releases.
As far as I know it is possibile to use rsync or webhooks (for example Git-Auto-Deploy) to get the build. However I failed to apply these options successfully.
For publishing releases I did read https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/api/tags.md#create-a-new-release, but im not sure if I understand the required pathing schema correctly.
Is there any simple complete example to try out this process?
A way is indeed to use webhooks:
There are tons of different possible solutions to do that. I'd go with a sh script which is invoked by the hook.
How to intercept your webhook is up to the configuration of your server, if you have php-fpm installed you can use a PHP script.
When you create a webhook in your Gitlab project (Settings->Webhooks) you can specify for which kind of events you want the hook (in our case, a new build), and a secret token so you can verify the script has been called by Gitlab.
The PHP script can be something like that:
<?php
// Check token
$security_file = parse_ini_file("../token.ini");
$gitlab_token = $_SERVER["HTTP_X_GITLAB_TOKEN"];
if ($gitlab_token !== $security_file["token"]) {
echo "error 403";
exit(0);
}
// Get data
$json = file_get_contents('php://input');
$data = json_decode($json, true);
// We want only success build on master
if ($data["ref"] !== "master" ||
$data["build_stage"] !== "deploy" ||
$data["build_status"] !== "success") {
exit(0);
}
// Execute the deploy script:
shell_exec("/usr/share/nginx/html/deploy.sh 2>&1");
I created a token.ini file outside the webroot, which is just one line:
token = supersecrettoken
In this way the endpoint can be called only by Gitlab itself. The script then checks some parameters of the build, and if everything is ok it runs the deploy script.
Also the deploy script is very very basic, but there are a couple of interesting things:
#!/bin/bash
# See 'Authentication' section here: http://docs.gitlab.com/ce/api/
SECRET_TOKEN=$PERSONAL_TOKEN
# The path where to put the static files
DEST="/usr/share/nginx/html/"
# The path to use as temporary working directory
TMP="/tmp/"
# Where to save the downloaded file
DOWNLOAD_FILE="site.zip";
cd $TMP;
wget --header="PRIVATE-TOKEN: $SECRET_TOKEN" "https://gitlab.com/api/v3/projects/774560/builds/artifacts/master/download?job=deploy_site" -O $DOWNLOAD_FILE;
ls;
unzip $DOWNLOAD_FILE;
# Whatever, do not do this in a real environment without any other check
rm -rf $DEST;
cp -r _site/ $DEST;
rm -rf _site/;
rm $DOWNLOAD_FILE;
First of all, the script has to be executable (chown +x deploy.sh) and it has to belong to the webserver’s user (usually www-data).
The script needs to have an access token (which you can create here) to access the data. I inserted it as environment variable:
sudo vi /etc/environment
in the file you have to add something like:
PERSONAL_TOKEN="supersecrettoken"
and then remember to reload the file:
source /etc/environment
You can check everything is alright doing sudo -u www-data echo PERSONAL_TOKEN and verify the token is printed in the terminal.
Now, the other interesting part of the script is where is the artifact. The last available build of a branch is reachable only through API; they are working on implementing the API in the web interface so you can always download the last version from the web.
The url of the API is
https://gitlab.example.com/api/v3/projects/projectid/builds/artifacts/branchname/download?job=jobname
While you can imagine what branchname and jobname are, the projectid is a bit more tricky to find.
It is included in the body of the webhook as projectid, but if you do not want to intercept the hook, you can go to the settings of your project, section Triggers, and there are examples of APIs calls: you can determine the project id from there.
So I run the following:
gsutil -m cp -R file.png gs://bucket/file.png
And I get the following error message:
Copying file://file.png [Content-Type=application/pdf]...
Uploading file.png: 42.59 KiB/42.59 KiB
AccessDeniedException: 401 Login Required
CommandException: 1 files/objects could not be transferred.
I'm not sure what the problem is since I ran config and I can see all my buckets. Does anyone know what I need to do?
Note: I do not have gcloud, I just installed gsutil and ran the config.
Login to Google Cloud is needed for accessing any Cloud service. You need to use below command which will guide you through login steps like typing verification code you generate by opening browser link given in console.
gcloud auth login
I was getting a similar response, and was able to solve this problem by looking at the read permissions on the .boto file. In my case, I was using a service account and the .boto file that was created by
gsutil config -e
only had read permissions set for user. Since it was being read by a service running as a different user, it wasn't able to read the file and yielding a 401 Login Required error. I fixed it by adding read permissions for the service's group.
In the least sophisticated case, you could fix it by giving any user read permission with
chmod a+r .boto
A more detailed explanation for troubleshooting
To get more information, run the same command with a -D flag, like:
gsutil -m -D cp ....
In the debug output, look at:
Command being run: /path/to/gsutil
config_file_list: /path/to/boto/config
Create your login credentials using the executable at /path/to/gsutil, not gcloud auth or any other gsutil executable on the machine, using:
/path/to/gsutil config
For a service account, use:
/path/to/gsutil config -e
These should create a .boto config file in your home directory, $HOME/.boto. If you are running the gsutil command this file should be referenced in the config_file_list variable in the debug output. If not, see below to change it.
Running gsutil under a service account or as another user
If you are running as another user, and need to reference a newly-created config file, set the environment variable BOTO_CONFIG (don't forget to export it):
BOTO_CONFIG=/path/to/$HOME/.boto
export BOTO_CONFIG
By setting this variable, when you execute gsutil, it will reference the config file you have placed in BOTO_CONFIG. You can confirm that you are referencing the correct config file by looking at the config_file_list variable in the gsutil -D command's output.
make sure the referenced .boto file is readable by the user who is executing the gsutil command
Running the /path/to/gsutil with the BOTO_CONFIG variable set allowed me to execute gsutil as another user, referencing an arbitrary BOTO_CONFIG file that was set up with a service-account's credentials.
To set up the service account:
https://console.cloud.google.com/permissions/serviceaccounts
The key file from the service account set-up process needs to be downloaded, and the path to it is requested during the gsutil config -e step.
This may be an issue with how gsutil/boto handles the OS path separators on Windows, as referenced here. This should eventually get merged into the sdk tools, but until then the following should work:
Go to
google-cloud-sdk\platform\gsutil\third_party\boto\boto\pyami\config.py
and replace the line:
for path in os.environ['BOTO_PATH'].split(':'):
with:
for path in os.environ['BOTO_PATH'].split(os.path.pathsep):
Next, go to
google-cloud-sdk\bin\bootstrapping\gsutil.py
replace the lines that use ':'
if boto_config:
boto_path = ':'.join([boto_config, gsutil_path])
elif boto_path:
# this is ':' for windows as well, hardcoded into the boto source.
boto_path = ':'.join([boto_path, gsutil_path])
else:
path_parts = ['/etc/boto.cfg',
os.path.expanduser(os.path.join('~', '.boto')),
gsutil_path]
boto_path = ':'.join(path_parts)
with
if boto_config:
boto_path = os.path.pathsep.join([boto_config, gsutil_path])
elif boto_path:
# this is ':' for windows as well, hardcoded into the boto source.
boto_path = os.path.pathsep.join([boto_path, gsutil_path])
else:
path_parts = ['/etc/boto.cfg',
os.path.expanduser(os.path.join('~', '.boto')),
gsutil_path]
boto_path = os.path.pathsep.join(path_parts)
Restart cmd and now the error should go away.